我的模型有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
中重新创建该文件。
所以我的问题是:为什么在FileField
中调用post_delete
的删除方法会阻止模型被删除?
答案 0 :(得分:5)
当您访问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
,它应该可以正常工作。
是的,我只是因为你的问题而查了一下。
答案 1 :(得分:1)
尝试django-cleanup,删除模型实例删除时删除旧文件,并在将新文件上传到FileField或ImageField时删除旧文件。