将内存zip文件写入Django FileField

时间:2019-01-24 13:43:15

标签: django django-file-upload

我正在尝试从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。

1 个答案:

答案 0 :(得分:1)

要将内存文件分配给FileField的{​​{1}},可以使用Model或更简单的子类InMemoryUploadedFile

此外,您不应使用SimpleUploadedFile的{​​{1}}函数,因为该函数仅执行数据库查询,而不会调用模型的QuerySet方法,该方法会将文件保存到磁盘:

因此,在您的代码中执行以下操作:

update()