djangomodelbulkimagefield

Override django's model delete method for bulk deletion


I'm overriding Django's model delete method in order to delete orphan files in the disk for image fields, something like this:

class Image(models.Model):
    img = models.ImageField(upload_to=get_image_path)
    ...
    def delete(self, *args, **kwargs):
        self.img.delete()
        super(Image, self).delete(*args, **kwargs)

This works fine when I delete single objects from the admin, but when I select multiple objects and delete them, this doesn't seem to get called. I have been googling for a while but haven't hit the right keywords to get the answer for this, nor the official documentation seems to talk about this subject.


Solution

  • It does:

    The delete() method does a bulk delete and does not call any delete() methods on your models. It does, however, emit the pre_delete and post_delete signals for all deleted objects (including cascaded deletions).

    For that to work, you can override delete method on QuerySet, and then apply that QuerySet as manager:

    class ImageQuerySet(models.QuerySet):
    
        def delete(self, *args, **kwargs):
            for obj in self:
                obj.img.delete()
            super(ImageQuerySet, self).delete(*args, **kwargs)
    
    class Image(models.Model):
        objects = ImageQuerySet.as_manager()
        img = models.ImageField(upload_to=get_image_path)
        ...
        def delete(self, *args, **kwargs):
            self.img.delete()
            super(Image, self).delete(*args, **kwargs)