我正在尝试从FileField中读取文件,将它们全部放入zip文件中,然后将该zip文件保存到另一个FileField中。 我试图避免使用临时文件,但似乎我可能必须这样做。
这是我到目前为止所得到的:
def generate_codified_batch(modeladmin, request, queryset):
for batch in queryset:
pieces = Pieces.objects.filter(batch=batch)
mem_zip = InMemoryZipFile(file_name=batch.name)
for piece in pieces:
in_file = open(piece.file.path, 'rb')
data = in_file.read()
mem_zip.append(filename_in_zip=f'/{piece.folder_assigned} /{piece.period}/{piece.codification}. \
{piece.file_name.rsplit(".")[-1]}'
, file_contents=data)
in_file.close()
files_codified = ContentFile(mem_zip.data)
Batches.objects.filter(pk=batch.id).update(file_codified=files_codified)
InMemoryZipFile是此数据包中的一个类:https://bitbucket.org/ruamel/std.zipfile/src/faa2c8fc9e0072f57857078059ded42192af5435/init.py?at=default&fileviewer=file-view-default#init.py-57
重要的只是最后两行
files_codified = ContentFile(mem_zip.data)
Batches.objects.filter(pk=batch.id).update(file_codified=files_codified)
mem_zip.data是InMemoryZip的属性,并返回bytes对象 (来自InMemoryZip类):
self.in_memory_data = StringIO()
@property
def data
return self.in_memory_data.getvalue()
我终生无法弄清如何从该字节对象读取并将其传递给FileField。
答案 0 :(得分:1)
要将内存文件分配给FileField
的{{1}},可以使用Model
或更简单的子类InMemoryUploadedFile
。
此外,您不应使用SimpleUploadedFile
的{{1}}函数,因为该函数仅执行数据库查询,而不会调用模型的QuerySet
方法,该方法会将文件保存到磁盘:
因此,在您的代码中执行以下操作:
update()