K09P
K09P

Reputation: 490

jQuery/Django retrieving file

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

Answers (1)

Abdul Aziz Barkat
Abdul Aziz Barkat

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

Related Questions