Reputation: 490
I have seen many answers to questions like this, but none has solved my problem...
I want to produce a pdf in the backend and then download it to the user. So I have a basic blank page with a button. For that button there is a jQuery function:
$.post("{% url 'printReport' %}",
{
'params' : JSON.stringify({
'reportcode' : 'HelloWorld',
})
}, function(data, status) {
$("#testZone").text(data)
});
On the server side, I produce the pdf and save it locally in the server folder. This goes perfect.
Then, in the views
file I have this:
def printRreport(request):
if request.method=="POST":
res = producePdf(request) #works fine! the PDF is birght an shiny, saved on the server
response = HttpResponse(res.data,content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="report.pdf"' #setting response headers
return response
where res.data
is actually open(pdf_path,'r').read()
this is 70% fine, because the browser actually receives the pdf data inside the request response (I can see it on the dev console). It's 30% wrong because this does not give me a download dialog and does not allow me to save a pdf file on the client side.
What is wrong here? In my case I opted by using a POST
method, I know it's debatable, but I don't think that is the problem...
Edit: I found a solution for this, maybe not optimal, but it works.
I marked below the answer I ended up following. I kept the code above, but I decided to generate the pdf file on the first view (which receives the POST
request), then redirect the user to another view where it would download it. And it works!
I'll still check this as suggested by Abdul though.
Thanks!
Upvotes: 0
Views: 169
Reputation: 21822
Instead of using HttpResponse try using FileResponse
:
from django.http import FileResponse
def printRreport(request):
res = producePdf(request)
file_ptr = # something that would get you something like open(pdf_path,'rb')
return FileResponse(file_ptr)
Now in your javascript the problem is you are making the request as ajax and the content is with javascript, an easier thing would be to let your browser handle the url (It is a file download anyway no need for ajax):
var link = document.createElement("a");
link.download = "Report";
link.href = "{% url 'printReport' %}";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Note: If you don't need to run this dynamically consider just an anchor with the url. Instead of javascript.
Upvotes: 1