下载一个完全在内存中使用 Django 创建的 zip 文件
Download a zip file created entirely in memory with Django
我需要生成几个 csv 报告,压缩并作为 zip 文件提供给用户。我使用 this snippet 作为参考
...
temp = StringIO.StringIO()
with zipfile.ZipFile(temp,'w') as archive:
for device in devices:
csv = Mymodel.get_csv_for(device)
archive.writestr('{}_device.csv'.format(device), str(csv))
response = HttpResponse(FileWrapper(temp), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="devices.zip"')
return response
查看 archive.listname()
我可以看到文件名。
查看 temp.getvalue()
我可以看到一些字符串,但是当我下载文件时它是空的。
您需要在 return 响应之前调用 temp.seek(0)
,否则 Python 将尝试从其末尾读取内存文件(写入存档后您将其留在的位置)到它),因此将找不到任何内容和 return 一个空的 HTTP 响应。
您还需要使用 StreamingHttpResponse
而不是 HttpResponse
。
那会得到:
...
temp = StringIO.StringIO()
with zipfile.ZipFile(temp,'w') as archive:
for device in devices:
csv = Mymodel.get_csv_for(device)
archive.writestr('{}_device.csv'.format(device), str(csv))
response = StreamingHttpResponse(FileWrapper(temp), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="devices.zip"')
response['Content-Length'] = temp.tell()
temp.seek(0)
return response
我需要生成几个 csv 报告,压缩并作为 zip 文件提供给用户。我使用 this snippet 作为参考
...
temp = StringIO.StringIO()
with zipfile.ZipFile(temp,'w') as archive:
for device in devices:
csv = Mymodel.get_csv_for(device)
archive.writestr('{}_device.csv'.format(device), str(csv))
response = HttpResponse(FileWrapper(temp), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="devices.zip"')
return response
查看 archive.listname()
我可以看到文件名。
查看 temp.getvalue()
我可以看到一些字符串,但是当我下载文件时它是空的。
您需要在 return 响应之前调用 temp.seek(0)
,否则 Python 将尝试从其末尾读取内存文件(写入存档后您将其留在的位置)到它),因此将找不到任何内容和 return 一个空的 HTTP 响应。
您还需要使用 StreamingHttpResponse
而不是 HttpResponse
。
那会得到:
...
temp = StringIO.StringIO()
with zipfile.ZipFile(temp,'w') as archive:
for device in devices:
csv = Mymodel.get_csv_for(device)
archive.writestr('{}_device.csv'.format(device), str(csv))
response = StreamingHttpResponse(FileWrapper(temp), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="devices.zip"')
response['Content-Length'] = temp.tell()
temp.seek(0)
return response