#python #django #amazon-s3 #boto3 #django-storage
#python #django #amazon-s3 #boto3 #django-storage
Вопрос:
Я использую django-storages, и пользовательский контент хранится в папках на S3. Теперь я хочу, чтобы пользователи имели возможность загружать все свои файлы сразу, предпочтительно в zip-файле. Все предыдущие сообщения, связанные с этим, устарели или не работают для меня.
Самый близкий к рабочему код, который у меня есть на данный момент:
from io import BytesIO
import zipfile
from django.conf import settings
from ..models import Something
from django.core.files.storage import default_storage
class DownloadIncomeTaxFiles(View):
def get(self, request, id):
itr = Something.objects.get(id=id)
files = itr.attachments
zfname = 'somezip.zip'
b = BytesIO()
with zipfile.ZipFile(b, 'w') as zf:
for current_file in files:
try:
fh = default_storage.open(current_file.file.name, "r")
zf.writestr(fh.name, bytes(fh.read()))
except Exception as e:
print(e)
response = HttpResponse(zf, content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename={}'.format(zfname)
return response
Это создает то, что выглядит как zip-файл, но единственным содержимым, которое у него есть, является ‘<zipfile.ZIP-файл [закрыт]>’
Я получил много разных результатов, в основном с ошибками, такими как zipfile, ожидающий содержимого строки или байтов при предоставлении файла FieldFile. На данный момент я полностью застрял.
Ответ №1:
Проблема заключалась в том, что мне нужно было вернуться к началу файла, добавив
zf.seek(0)
непосредственно перед возвратом файла в HttpResponse.
Ответ №2:
Здесь есть 2 проблемы. первое заключается в том, что, даже если вы создаете zip-файл, вы записываете данные в объект bytesio, и второе, вам нужно навести курсор в начале, поскольку writer будет указывать на конец. Так что это должно быть:
b.seek(0)
response = HttpResponse(b, content_type="application/x-zip-compressed")