关于简易缩略图:Django easy_thumbnails和post_delete

Django easy_thumbnails and post_delete

我正在从表单中删除一个相关的模型(几乎与django admin相同),我有一个包含很多图像的项目,图像属于Item(ForeignKey)。
我已经实现了一个post_delete信号,用于在从表单中删除图像时删除缩略图和图像,问题是在post_delete缩略图中删除了图像,但数据库中的图像条目仍然保留:

1
2
3
4
5
6
7
8
9
# Auto-delete files from filesystem when they are unneeded:
@receiver(models.signals.post_delete, sender=ImageModel)
def auto_delete_file_on_delete(sender, instance, **kwargs):
   """Deletes file from filesystem
    when corresponding `ImageModel` object is deleted.
   """
    if instance.imagefile:
        thumbmanager = get_thumbnailer(instance.imagefile)
        thumbmanager.delete()

如果最后添加以下内容,则图像实例也将被删除(预期行为):

1
2
3
4
5
6
7
8
9
10
# Auto-delete files from filesystem when they are unneeded:
@receiver(models.signals.post_delete, sender=ImageModel)
def auto_delete_file_on_delete(sender, instance, **kwargs):
   """Deletes file from filesystem
    when corresponding `ImageModel` object is deleted.
   """
    if instance.imagefile:
        thumbmanager = get_thumbnailer(instance.imagefile)
        thumbmanager.delete()
        instance.delete()

我想念什么吗?删除实例后不应该发送post_delete信号吗?为什么实例保留在数据库中?
我认为这与Queryset删除行为有关,但是我对此表示怀疑,因为如果删除信号,则会删除ImageModel实例(尽管缩略图确实保留在数据库中)。
请注意,模型使用ImageField字段中的django构建,而不是提供字段的简单缩略图:

1
2
3
4
5
class ImageModel(models.Model):
    ...
    imagefile = models.ImageField(upload_to="properties/%m/%Y")
    item = models.ForeignKey('app.ItemModel', related_name='images')
    ...

上面的解决方案(instance.delete())毫无问题,只是对行为感到好奇。


您也可以使用django-cleanup,当您删除模型时,它将自动在FileField上调用delete方法。

1
pip install django-cleanup

settings.py

1
2
3
4
INSTALLED_APPS = (
     ...
    'django_cleanup', # should go after your apps
)


好的,它可以添加delete(save = False):

1
2
3
4
5
6
7
8
9
# These two auto-delete files from filesystem when they are unneeded:
@receiver(models.signals.post_delete, sender=ImageModel)
def auto_delete_file_on_delete(sender, instance, **kwargs):
   """Deletes file from filesystem
    when corresponding `ImageModel` object is deleted.
   """
    if instance.imagefile:
        thumbmanager = get_thumbnailer(instance.imagefile)
        thumbmanager.delete(save=False)