1

I am trying to set up a django button so I can download a file. I tried following along a tutorial but I think i'm missing something. The urls.py code below is the urls.py file that i generated in the app section of my project. I am not sure if that is the correct one to be using. The code below is not working, local host doesn't load the page. however when i comment out url('download_my_pdf', download_pdf), in my urls.py the site loads as we dont have that link back to the code in the views.

INDEX.HTML:

<input type="button" value="Download" onclick="window.open('download_my_pdf')">

VIEWS.PY:

from django.shortcuts import render
from django.http import HttpResponse
from wsgiref.util import FileWrapper

def index(request):
return render(request, "index.html", {})

def home(request):
return render(request, "home.html", {})

def download_pdf(request):
filename = 'faults.pdf'
content = FileWrapper(filename)
response = HttpResponse(content, content_type='application/pdf')
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=%s' % 'faults.pdf'
return response

URLS.PY

from django.urls import url
from django.urls import path

from . import views

urlpatterns = [
 path('', views.index, name="index"),
 path('home', views.home, name="home"),
 url('download_my_pdf', download_pdf),
]

enter image description here

kitchen800
  • 197
  • 1
  • 12
  • 36
  • update `url('download_my_pdf', download_pdf),` ______________ to ______________ `path('download_my_pdf', views.download_pdf),` – Ben Jun 19 '20 at 23:56
  • When great the site loads, however when i click the download button now it throw 'str' object has no attribute 'read' error. so no file is actually downloaded. It hi lights line 16 in my views.py: response = HttpResponse(content, content_type='application/pdf') – kitchen800 Jun 20 '20 at 11:34

3 Answers3

2

views.py

from django.http import HttpResponse, Http404

def open_file(request, *args, **kwargs):
    path = str(kwargs['p'])

    file_path = 'your path'
    if os.path.exists(file_path):
        with open(file_path, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
            response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
            return response
    raise Http404

templates/template.html

                            <a class="button" href="{% url 'open-file' path %}">Download</a>

urls.py

path('open/<str:path>/', views.open_file, name='open-file'),
o.al
  • 36
  • 2
  • Welcome to Stack Overflow! Please try to be as clear and complete in your answer as possible. Try adding some explanation besides adding code. – sebasaenz Jun 20 '20 at 00:45
0

for your code, try to "views.download_pdf" in your urls file, you 're using it without importing it

o.al
  • 36
  • 2
  • When great the site loads, however when i click the download button now it throw `'str' object has no attribute 'read'` error. so no file is actually downloaded. It hi lights line 16 in my views.py: `response = HttpResponse(content, content_type='application/pdf')` – kitchen800 Jun 20 '20 at 09:42
0

As others have already suggested, your urls.py has an error. You're missing the views.download_pdf part. I would also suggest naming it so it can be used in the future for a possible reverse function. Also, for consistency and simplicity, it is best to stick to the path function. The URL function is an alias of the re_path function that allows regex functionality, but this is not needed for your problem.

Django url reference

from django.urls import url
from django.urls import path

from . import views

urlpatterns = [
 path('', views.index, name="index"),
 path('home', views.home, name="home"),
 path('download_my_pdf', views.download_pdf, name="download_pdf"),
]

With the URL routing set, one can create a download button. I prefer the below button. It looks like a button because it holds the bootstrap class, but underneath it is a simple link to your download_pdf view.

<a class="btn btn-primary" href="{% url 'download_pdf' %}" role="button">Download pdf</a>

After pushing the button link you get redirected to your download_pdf view. This should activate the download. I did not test your view code. If it still does not work, let me know. There might be another option involving PdfFileReader. Example

It might be possible to read your file with PdfFileReader and then return it in your download_pdf view. Good luck!