Django howto progessive write data into the huge zipfile FileField
У меня есть django такая модель:
class Todo(models.Model):
big_file = models.FileField(blank=True)
status = models.PositiveSmallIntegerField(default=0)
progress = models.IntegerField(default=0)
Я хотел бы выполнить две операции:
- сначала создайте пустой zip-файл из
big_file(менее важно) - и затем постепенно добавлять файлы в мой zip-файл (и сохранять его итеративно)
Общий процесс будет выглядеть следующим образом:
from django.core.files.base import File
import io, zipfile
def generate_data(todo):
io_bytes = io.BytesIO(b'')
# 1. save an empty Zip archive:
with zipfile.ZipFile(io_bytes, 'w') as zip_fd:
todo.generated_data.save('heavy_file.zip', File(zip_fd))
# 2. Progressively fill the Zip archive:
with zipfile.ZipFile(io_bytes, 'w') zip_fd:
for filename, data_bytes in long_iteration(todo):
with zip_fd.open(filename, 'w') as in_zip:
in_zip.write(data_bytes)
if condition(something):
todo.generated_data.save() # that does not work
todo.status = 1
todo.progress = 123
todo.save()
todo.status = 2
todo.save()
Но я не могу найти правильную комбинацию filedescriptor / file-like object / Filepath / django-File object ...
И кажется, что в django я всегда должен save(filename, content). Но мое содержимое может быть гигабайтами, так что не кажется разумным хранить все это в переменной "content"?
Ок Я нашел следующее решение для себя; сначала создайте пустой файл, а затем используйте атрибут <my_file_field>.path:
def generate_data(todo):
# 1. save an empty Zip archive:
todo.big_file.save('filename.zip', ContentFile(''))
with zipfile.ZipFile(todo.big_file.path, 'w') as zip_fd:
pass
# 2. Progressively fill the Zip archive:
with zipfile.ZipFile(todo.big_file.path, 'w') zip_fd:
... # do the stuff