如何在Django中直接从urllib渲染PDF并实现下载,无需保存文件
我以前总是把想要让用户下载的文件保存在django中。在我的项目里,我用的代码比如说:
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
我有一个pdf文件,是通过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)
现在我把这个pdf文件保存为report.pdf。但是我的目标是直接把它显示在我的模板里,使用django中的一个函数。这可能吗?
1 个回答
2
在Django 1.5版本中,新增了一个叫做StreamingHttpResponse
的类,可以用来根据一个迭代器来逐步发送响应。你的视图和迭代器可以像这样:
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
在Django 1.5之前,你也可以通过将一个迭代器传给HttpResponse
来逐步发送响应,但这样做有几个注意事项。首先,你需要在你的视图函数上使用@condition(etag_func=None)
这个装饰器。其次,有些中间件可能会阻止正确的逐步响应,所以你需要绕过这些中间件。最后,只有当内容的长度达到1024字节时,才会发送一部分内容,所以chunk_size
应该设置为超过1024。