将 ZipFile 保存到 Django 中的 FileField

问题描述

我在 Django 中有以下模型:

class AksOrder(models.Model):
    zip_file = models.FileField(upload_to='aks_zips/%M/%s/',blank=True)

在我看来,我有以下基本功能

def gen_zip(pk,name,vars):
    zipObj = ZipFile(os.path.join('/tmp/',str(name) + '_' + str(pk) + '.zip'),'w')
    zipObj.write(pdf_files[0].path,'/filea.pdf')
    zipObj.write(pdf_files[1].path,'/fileb.pdf')

def aksorder_complete(request,pk):
    ao = get_object_or_404(AksOrder,id=pk)
    zipObj = generate_shop_zip(ao.c.pk,ao.dl,ao.vars)
    ao.zip_file.save('file.zip',zipObj)

我不仅尝试了这个版本,而且这个版本对我来说似乎是最合理、最合乎逻辑的一个。我得到一个 There is no item named 65536 in the archive。当我稍微修改它并在第一个函数的 zip 写入结束时关闭文件时,我收到一条 ValueError: Attempt to use ZIP archive that was already closed 消息。两次,zip 文件都在 /tmp/ 中正确生成,我无法解决它。而且这只是本地的,我需要稍后为 S3 做...

解决方法

我终于实现了:我在最后的第一个函数中添加了一个 zipObj.close(),并像这样修改了第二个函数:

file = open('path/to/file.zip','rb')
ao.zip_file.save('name.zip',file)

显然,文件打开中的 rb 模式是决定性的。