4

我有一个模型FileField

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

当您使用 a 删除模型实例时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_deletepost_delete它的行为应如此。我能想到的唯一会导致这种行为的是,如果从FileField自动保存模型中删除文件,这将导致它在post_delete.

所以我的问题是:为什么调用 aFileField的 delete 方法来post_delete防止模型被删除?

4

2 回答 2

6

当您访问一个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=Falsedelete 方法,它应该可以工作。

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

于 2012-05-05T01:04:12.060 回答
1

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

于 2012-08-21T15:57:46.370 回答