【问题标题】:Can't delete FileField's file in post_delete无法在 post_delete 中删除 FileField 的文件
【发布时间】:2012-05-14 07:48:56
【问题描述】:

我有一个带有FileField 的模型:

class FileModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=200)
    file = models.FileField(upload_to='myfiles')

当你删除带有FileField的模型实例时,django不会自动从文件系统中删除底层文件,所以我设置了一个信号来删除post_delete上的底层文件:

def on_delete(sender, instance, **kwargs):
    instance.file.delete()

models.signals.post_delete.connect(on_delete, sender=FileModel)

问题是,当我删除 FileModel 对象(比如说从 django 管理页面)时,它会从文件系统中删除文件,但不会删除模型。如果我再次删除它,它会删除模型,但是当它尝试从文件系统中删除文件时会引发异常,因为该文件不存在。

当我将文件删除更改为在pre_delete 而不是post_delete 上发生时,它的行为应如此。我能想到的唯一会导致这种行为的事情是,如果从 FileField 中删除文件会自动保存模型,这将导致它在 post_delete 中重新创建。

所以我的问题是:为什么在post_delete 中调用FileField 的删除方法会阻止模型被删除?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    当您访问 FileField 属性时,您将获得一个 FieldFile 包装器实例。现在猜猜它的.delete 方法的代码是什么... (摘自 django.db.models.fields.files)

    def delete(self, save=True):
            # Only close the file if it's already open, which we know by the
            # presence of self._file
            if hasattr(self, '_file'):
                self.close()
                del self.file
    
            self.storage.delete(self.name)
    
            self.name = None
            setattr(self.instance, self.field.name, self.name)
    
            # Delete the filesize cache
            if hasattr(self, '_size'):
                del self._size
            self._committed = False
    
            if save:
                self.instance.save()
    

    所以你是对的:)

    如果我没看错,您现在可以再次将其连接到 post_delete 信号并将 save=False 传递给 delete 方法,它应该可以工作。

    是的,我只是因为你的问题才查到的。

    【讨论】:

    • 感谢您抽出宝贵时间对此进行彻底调查。
    【解决方案2】:

    试试django-cleanup,它会在删除模型实例时删除旧文件,并在您将新文件上传到 FileField 或 ImageField 时删除旧文件。

    【讨论】:

    • 这很好,但是现在很多文件实际上是上传到CDN,而不是存储在本地。
    猜你喜欢
    • 2018-12-14
    • 2016-01-09
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 2014-12-18
    • 1970-01-01
    相关资源
    最近更新 更多