Django 解压文件并将内容添加到数据库

0 投票
2 回答
2375 浏览
提问于 2025-04-16 23:12

我正在尝试创建一个系统,让管理员可以上传一个压缩文件(zip文件),然后这个脚本会自动使用 signals 解压缩它,查找所有的 jpgpng 文件,创建一个文件列表,并根据这些文件生成数据库记录。

在我的模型中,有 ProjectPhoto 两个表,Photo 表和 Project 表之间有一种叫做 Many-to-One 的关系,也就是外键关系。

下面的脚本是我正在使用的信号。我可以顺利获取到 instance.file_zip.path,而且当手动运行这个脚本时,它工作得很好。

经过长时间的调试,我认为 belongs_to=instance 可能有问题,但我不知道该怎么修复,因为我并不完全理解为什么会出现错误。解压缩的部分运行得很好,我把它放在这里只是供参考,你很可能不需要阅读和理解它。

@receiver(post_save, sender=Project)
def unzip_and_process(sender, instance, **kwargs):
    #project_zip = FieldFile.open(file_zip, mode='rb')
    file_path = instance.file_zip.path
    file_list = []
    with zipfile.ZipFile(file_path, 'r') as project_zip:
        project_zip.extractall(re.search('[^\s]+(?=\.zip)', file_path).group(0))
        project_zip.close()
    for root, dirs, files in os.walk(file_path):
        for filename in files:
            file_list.append(os.path.join(root, filename))
    photo_list = filter(filter_photos, file_list)
    for photo in photo_list:
        print 'Processing %s'%photo
        p = Photo.objects.create(belongs_to=instance, img=photo, desc='Processed from zipfile')
        p.save()

更新

class Project(models.Model):
    project_name=models.CharField(max_length=150)
    date_taken=models.DateField()
    date_deadline=models.DateField()
    price=models.FloatField()
    price_paid=models.BooleanField()
    owner=models.ForeignKey(User)
    file_zip=models.FileField(upload_to='projects/%Y/%m/%d')

    def __unicode__(self):
        return self.project_name

    def file_path(self):
        return re.search('[^\s]+(?=\.zip)', self.file_zip.name).group(0)

class Photo(models.Model):

    def project_path(instance, filename):
        return '%s/%s'%(instance.belongs_to.file_path(),filename)

    belongs_to=models.ForeignKey(Project, verbose_name="related_project")
    img=models.ImageField(upload_to=project_path, max_length=255)
    desc=models.CharField(max_length=255)

    def __unicode__(self):
        return '%s FROM [%s]'%(self.img.name,self.belongs_to)

2 个回答

2

django-photologue正好有你需要的东西,他们还做了一个类似的技巧,可以上传压缩文件(zip文件)。

链接:http://code.google.com/p/django-photologue/,如果你不想自己去搜索的话。

更重要的是,上传压缩文件的类叫做GalleryUpload(models.Model)。

1
for root, dirs, files in os.walk(file_path):

file_path 指的是一个 zip 文件,而不是一个 目录,所以 os.walk 不会返回任何内容。

撰写回答