Domanda

I am deleting a related model from a form (nearly the same way as django admin), I have an item which has many images, image belongs to Item (ForeignKey). I have implemented a post_delete signal to delete thumbnails and the image when deleting the image/images from the form, the problem is that in the post_delete thumbnails are deleted but the image entry in the db remains:

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

If I add the following in the end, the image instance is also deleted (expected behavior):

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

Am I missing something? Shouldn't the post_delete signal be sent after deleting the instance? Why is the instance persisted in the db? I assume that this has to do with Queryset delete behavior, but I am sceptical to it since If I remove the signal then the instance of ImageModel is deleted (though thumbnails do remain in the database). Mind that the model uses the django build in ImageField field, and not easy thumbnails provided fields:

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

The above solution (instance.delete()) is working with no problems, just curious about the behavior.

È stato utile?

Soluzione 2

Ok got it working with adding 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)

Altri suggerimenti

You can also use django-cleanup, it automatically invokes delete method on FileField when you remove model.

pip install django-cleanup

settings.py

INSTALLED_APPS = (
     ...
    'django_cleanup', # should go after your apps
)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top