How do I override delete() on a model and have it still work with related deletes How do I override delete() on a model and have it still work with related deletes python python

How do I override delete() on a model and have it still work with related deletes


I'm doing the same thing and noticed a nugget in the Django docs that you should think about.

Overriding predefined model methods

Overriding Delete Note that the delete() method for an object is not necessarily called when deleting objects in bulk using a QuerySet. To ensure customized delete logic gets executed, you can use pre_delete and/or post_delete signals.

This means your snippet will not always do what you want. Using Signals is a better option for dealing with deletions.

I went with the following:

import shutilfrom django.db.models.signals import pre_delete from django.dispatch import receiver@receiver(pre_delete)def delete_repo(sender, instance, **kwargs):    if sender == Set:        shutil.rmtree(instance.repo)


I figured it out. I just put this on that Widget model:

def delete(self):    files = WidgetFile.objects.filter(widget=self)    if files:        for file in files:            file.delete()    super(Widget, self).delete()

This triggered the necessary delete() method on each of the related objects, thus triggering my custom file deleting code. It's more database expensive yes, but when you're trying to delete files on a hard drive anyway, it's not such a big expense to hit the db a few extra times.


Using clear() prior to deleting, removes all objects from the related object set.

see django-following-relationships-backward

example:

group.link_set.clear() group.delete()