Django easy_thumbnails и post_delete

Я удаляю связанную модель из формы (почти так же, как администратор django), у меня есть элемент, который имеет много изображений, изображение принадлежит Item (ForeignKey). Я реализовал сигнал post_delete для удаления миниатюр и изображения при удалении изображения / изображений из формы, проблема в том, что в post_delete миниатюры удаляются, но запись изображения в БД остается:

# 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()

Если в конце я добавлю следующее, экземпляр изображения также будет удален (ожидаемое поведение):

# 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 удаляется (хотя миниатюры остаются в базе данных). Имейте в виду, что модель использует сборку django в поле ImageField, а не простые миниатюры предоставленных полей:

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

Приведенное выше решение (instance.delete()) работает без проблем, просто интересует поведение.

2 ответа

Решение

Хорошо, это работает с добавлением delete (save = False):

# 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)

Вы также можете использовать django-cleanup, он автоматически вызывает метод удаления в FileField при удалении модели.

pip install django-cleanup

settings.py

INSTALLED_APPS = (
     ...
    'django_cleanup', # should go after your apps
)
Другие вопросы по тегам