1

I am new to Django and I need some assistance. I want to download the file whose path is in plik.localisation (it has been taken from a loop). The problem is with the path. Could someone help me? What am I doing wrong?

My view.py is:

def download(request, path):
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
        with open(file_path, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/pdf")
            response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
            return response
    raise Http404

Urls

    path('download/<str:path>',views.download, name="download"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Html

<div class="com">
       {{plik.localisation}} <a href="{% url 'download/path' %}" class="button">download</a>
</div>

I've tried to change that path but still have problem with it.

8
  • 1. There is no path() with the name 'download/path' in the urlpatterns list you shared so you will get a 404 HTTP response status when you click that anchor tag. There is "download" though. But what will be the argument for that View then? 2. If you use "download/path" as the argument for that View but you do not have a file "download/path" in your settings.MEDIA_ROOT, the if block will never be entered so you will get a 404 HTTP response status also. If you understood this comment I’ll write an answer but if you didn’t, ask for more clarification. Commented Jun 13 at 19:01
  • use FileResponse instead of HttpResponse Commented Jun 13 at 23:04
  • @ChukwujiobiCanon, could you write me a an answer, how should looks like? And also a href is wrong, I tried everyting. Commented Jun 14 at 7:17
  • Has this been solved? Commented Jun 15 at 14:40
  • Okay share the Model for the QuerySet plik. Commented Jun 16 at 17:26

2 Answers 2

0

There is no path() with the name 'download/path' in your urlpatterns so you will get a 404 HTTP response status when you click that anchor tag.

What you want is:

<div class="com">
    <a href="{% url 'download' plik.localisation %}" class="button">download</a>
</div>

Aside:

Do you want to show the file as part of a webpage (considering that you are using header Content-Disposition: inline)? If so, why give the anchor tag a text that says "download"? If it is meant to be downloaded by the client, then this is what the server code should look like:

#•••Rest of code•••
if os.path.exists(file_path):
    return FileResponse(open(file_path, 'rb'), as_attachment=True, filename=os.path.basename(file_path)) #[1]

If the file is meant to be shown as part of a webpage, then the anchor tag’s text shouldn’t be "download". That is misleading. It probably should be "view", "open" or any other variant of the same message since it won’t be downloaded. Then your code would be:

#•••Rest of code•••
if os.path.exists(file_path):
    return FileResponse(open(file_path, 'rb'), filename=os.path.basename(file_path))[2]

[1] The Content-Type header is automatically set when it can be guessed from the filename, or the name of open_file so no need for "application/pdf".

[2] as_attachment is False by default. Content-Disposition: inline will now be the header set.

27
  • I want to be downloaded by the client. I still have problem with the url: {{plik.localisation}} <a href="{% url 'download' plik.localisation %}" class="button">download</a> Reverse for 'download' with arguments '('',)' not found. 1 pattern(s) tried: ['download/(?P<path>[^/]+)/\\Z'] Commented Jun 14 at 7:28
  • The argument serve in your path() is for what by the way? If you want to pass extra keyword arguments to the View, it should look like this: some_arg=serve. But is serve defined? If it is a mistake, remove it and try again. Commented Jun 14 at 7:43
  • Os sorry, I already delete it, it looks like that: 'path('download/<path>/',views.download, name="download")' Commented Jun 14 at 7:45
  • Nope I have that info Reverse for 'download' with arguments '('',)' not found. 1 pattern(s) tried: ['download/(?P<path>[^/]+)/\\Z'] Commented Jun 14 at 7:53
  • Make sure that plik.localisation has a valid value that is not "" —empty str. It is required not to be an empty str. Commented Jun 14 at 7:54
-1

This code works def download(request, path): with open(path, 'rb') as fh: if os.path.exists(path): return FileResponse(open(path, 'rb'), as_attachment=True, filename=os.path.basename(path)) raise Http404

2
  • That’s my code is it not? Without the with Context of course. You don’t even need the Context so remove it. So the path didn’t have to be concatenated with settings.MEDIA_URL after all just like I said. Well congrats. One upvote from me although I’ve got to say that I deserve the accepted answer after all I went through to get this to work. Cheers :) Commented Jun 17 at 11:37
  • The code has a redundancy issue. The file is opened twice. Also, the os.path.exists(path) check should be done before opening the file. Consider revising the code for efficiency and correctness. Commented Jun 18 at 19:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.