如何在 django 中提供可下载的 zip 文件

Posted

技术标签:

【中文标题】如何在 django 中提供可下载的 zip 文件【英文标题】:how to serve downloadable zip file in django 【发布时间】:2013-10-27 20:47:18 【问题描述】:

我正在查看 django 文档,发现这段代码可以让您将文件呈现为附件

dl = loader.get_template('files/foo.zip')
context = RequestContext(request)
response = HttpResponse(dl.render(context), content_type = 'application/force-download')
response['Content-Disposition'] = 'attachment; filename="%s"' % 'foo.zip'
return response

foo.zip 文件是使用 pythons zipfile.ZipFile().writestr 方法创建的

zip = zipfile.ZipFile('foo.zip', 'a', zipfile.ZIP_DEFLATED)
zipinfo = zipfile.ZipInfo('helloworld.txt', date_time=time.localtime(time.time()))
zipinfo.create_system = 1
zip.writestr(zipinfo, StringIO.StringIO('helloworld').getvalue())
zip.close()

但是当我尝试上面的代码来渲染文件时,我得到了这个错误

'utf8' 编解码器无法解码位置 10 中的字节 0x89:无效起始字节

关于如何正确执行此操作的任何建议?

【问题讨论】:

为什么要渲染一个 .zip 文件的模板?您确定这是提供文件的文档中的内容吗? 你好,我正在尝试将其呈现为附件。据我所知,您可以在 django 响应中指定要吐出的内容类型,类似于上面的代码 您确定 render 是您想要的正确词吗?我宁愿认为您只是想提供它供人们下载,对吗? 如果你是这样定义的,好吧。底线是使文件可在 django 中下载。 ***.com/questions/1156246/… 【参考方案1】:

我认为您想要的是提供一个文件供人们下载。如果是这样,你不需要渲染文件,它不是模板,你只需要serve it as attachment using Django's HttpResponse:

zip_file = open(path_to_file, 'r')
response = HttpResponse(zip_file, content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="%s"' % 'foo.zip'
return response

【讨论】:

只是关于这个解决方案的一个问题,python的open()在作用域后会自动关闭吗?有了这个,您无法关闭流,直到您将其返回以使其工作。谢谢。 ***.com/questions/2404430/… @helloworld2013:对不起,我不在线。我猜你已经回答了你的问题:)。 (简而言之)当 zip_file 超出范围并进行垃圾收集时,文件的资源将被释放。【参考方案2】:

FileResponse 优先于 HttpResponse 用于二进制文件。此外,以'rb' 模式打开文件会阻止UnicodeDecodeError

zip_file = open(path_to_file, 'rb')
return FileResponse(zip_file)

【讨论】:

这对我来说效果很好。有关指定目标文件名等更多参数,请参阅docs.djangoproject.com/en/3.0/ref/request-response/…。

以上是关于如何在 django 中提供可下载的 zip 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何通过可下载的链接将文本保存为 .txt 文件?

从 JavaScript 创建一个可下载的附件?

使用 .Net 为 Apple 存折创建可下载的通行证 (*.pkpass)

如何在CodeIgniter中将上载的文件(PDF,DOC等)显示为可下载的链接

ExtJS 4.2 将网格数据导出到可下载的 CSV 文件

如何在 youtube 上获取可下载的直播视频 URL