Reputation: 79
I am uploading a file and saving it on a folder outside the media folder. I want to add a download link in a template to be able to download the file directly. I am not sure what to add in the URL, if I should add something
I tried this in the template it says URL not found
<a href="{{data.tar_gif.url}}"> Download File</a>
views.py
def uploaddata(request):
if request.user.is_authenticated:
if request.method == 'POST':
form = uploadform(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('file_list')
else:
form = uploadmetaform()
return render(request, 'uploaddata.html', {
'form': form
})
else:
return render(request, 'home.html')
HTML page
<tbody>
{% for data in dataset %}
<tr>
<td>{{data.path_id}}</td>
<td>{{ data.tar_gif }}</td>
<td>
<a href="{{data.document.url}}"> Download File</a>
</td>
</tr>
{% endfor %}
</tbody>
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Assigned_Group= models.CharField(max_length=500, choices=Group_choices, default='Please Select')
def __str__(self):
return self.user.username
def nice_user_folder_upload(instance, filename):
extension = filename.split(".")[-1]
return (
f"{instance.user_profile.Assigned_Group}/{filename}"
)
class uploadmeta(models.Model):
path = models.ForeignKey(Metadataform, on_delete=models.CASCADE)
user_profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True, verbose_name='Username')
document = models.FileField(upload_to=nice_user_folder_upload, verbose_name="Dataset") # validators=[FileExtensionValidator(allowed_extensions=['tar', 'zip'])]
def __str__(self):
return self.request.user
Upvotes: 2
Views: 7392
Reputation: 379
1.settings.py:
MEDIA_DIR = os.path.join(BASE_DIR,'media')
#Media
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
2.urls.py:
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
3.in template:
<a href="{{ file.url }}" download>Download File.</a>
for more detail use this link: https://youtu.be/MpDZ34mEJ5Y
Upvotes: 4
Reputation: 31
Look at this post: How to serve downloadable files using Django (Chris Gregori) ?
Maybe a better way to not expose the path of the files, even the names if you do want to do that. I do not like the idea to show the structure of the paths to users. Other things you can accomplish with this is to validate who can download the files if you check the request.user with your database for every file is served, and it is pretty simple.
Basically, the publication refers to using the xsendfile module so django generates the path to the file (or the file itself), but the actual file serving is handled by Apache/Lighttpd. Once you've set up mod_xsendfile, integrating with your view takes a few lines of code:"
from django.utils.encoding import smart_str
response = HttpResponse(mimetype='application/force-download') # mimetype is replaced by content_type for django 1.7
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
# It's usually a good idea to set the 'Content-Length' header too.
# You can also set any other required headers: Cache-Control, etc.
return response
As I said before, I do not like the idea of having published the path to the file.
With this pointer to the information, you can research and get this working.
Hope it works for you.
Upvotes: 0
Reputation: 126
Actually simple way of doing it by using html download attribute the way you achieve this is by
<a href="{{data.document.url}}" download> Download File</a>
or you also use :
<a href="{{ data.document.url }}" download="{{ data.document.url }}"> Download File</a>
Upvotes: 6