Мне нужно создать несколько отчетов csv, сжать и использовать zip для пользователя. Я использую этот фрагмент в качестве ссылки
...
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()
я вижу некоторую строку, но когда я загружаю файл, он выходит пустым.
Вам нужно вызвать temp.seek(0)
прежде чем вернуть ответ, иначе Python попытается прочитать файл памяти с его конца (где вы оставили его после записи в него архива) и, следовательно, не найдете никакого содержимого и не вернете пустой 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