将内存 zip 文件写入 django FileField
Writing in memory zip file to django FileField
我正在尝试从 FileField 读取文件,将它们全部压缩并将该 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 是来自此数据包的 class: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 和 returns 字节的对象
(来自 InMemoryZip class):
self.in_memory_data = StringIO()
@property
def data
return self.in_memory_data.getvalue()
我这辈子都想不出如何从该字节对象中读取并将其传递给 FileField。
要将内存中的文件分配给 Model
的 FileField
,您可以使用 InMemoryUploadedFile
或者更简单的子类 SimpleUploadedFile
.
此外,您不应使用 QuerySet
的 update()
函数,因为它仅执行数据库查询,但不会调用模型的 save()
方法来保存文件到磁盘:
所以在你的代码中这样做:
files_codified = SimpleUploadedFile.from_dict({
'content': mem_zip.data,
'filename': batch.name + ".zip",
'content-type': 'application/zip'})
batch.files_codified = files_codified
batch.save()
我正在尝试从 FileField 读取文件,将它们全部压缩并将该 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 是来自此数据包的 class: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 和 returns 字节的对象 (来自 InMemoryZip class):
self.in_memory_data = StringIO()
@property
def data
return self.in_memory_data.getvalue()
我这辈子都想不出如何从该字节对象中读取并将其传递给 FileField。
要将内存中的文件分配给 Model
的 FileField
,您可以使用 InMemoryUploadedFile
或者更简单的子类 SimpleUploadedFile
.
此外,您不应使用 QuerySet
的 update()
函数,因为它仅执行数据库查询,但不会调用模型的 save()
方法来保存文件到磁盘:
所以在你的代码中这样做:
files_codified = SimpleUploadedFile.from_dict({
'content': mem_zip.data,
'filename': batch.name + ".zip",
'content-type': 'application/zip'})
batch.files_codified = files_codified
batch.save()