Directly render pdf from urllib with out saving the file and then make it downloadable in django

StackOverflow https://stackoverflow.com/questions/22987992

  •  01-07-2023
  •  | 
  •  

Question

I always used to save the files I wanted to make downloadable in django. In my project I used that code for example:

def keyDownload(request, benutzername):
        benutzernameKey = benutzername +".key"
        fsock = open('/var/www/openvpn/examples/easy-rsa/2.0/keys/'+benutzernameKey, 'r')
        response = HttpResponse(fsock, mimetype='application/pgp-keys')
        response['Content-Disposition'] = "attachment; filename = %s " % (benutzernameKey)
        return response

I got a pdf file which I get through urllib:

url = "http://www.urltomypdf.com"
sock = urllib2.urlopen(url)
with open('report.pdf', 'wb') as f:
    while True:
        content = sock.read()
        if not content: break
        f.write(content)

At the moment I am saving the pdf in a file called report.pdf. But my aim is to render it directly to my template with a function in django. Is that possible ?

Était-ce utile?

La solution

With the introduction of Django 1.5, the StreamingHttpResponse class has been made available to stream a response based on an iterator. Your view and iterator could look like this:

def stream_pdf(url, chunk_size=8192):
    sock = urllib2.urlopen(url)
    while True:
        content = sock.read(chunk_size)
        if not content: break
        yield content

def external_pdf_view(request, *args, **kwargs):
    url = <url> # specify the url here
    response = StreamingHttpResponse(stream_pdf(url), content_type="application/pdf")
    response['Content-Disposition'] = "filename='%s'" % <filename> #specify the filename here
    return response

Pre Django 1.5, it is still possible to stream a response by passing an iterator to HttpResponse, but there are several caveats. First, you need to use the @condition(etag_func=None) decorator on your view function. Secondly, some middleware can prevent a properly streamed response, so you'll need to bypass that middleware. And finally, a chunk of content only gets send when it reaches a length of 1024 bytes, so chunk_size should be over 1024.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top