What are the options for overriding Django's cascading delete behaviour?

Posted by Tom on Stack Overflow See other posts from Stack Overflow or by Tom
Published on 2010-03-19T05:56:06Z Indexed on 2010/03/19 6:01 UTC
Read the original article Hit count: 290

Django models generally handle the ON DELETE CASCADE behaviour quite adequately (in a way that works on databases that don't support it natively.)

However, I'm struggling to discover what is the best way to override this behaviour where it is not appropriate, in the following scenarios for example:

  • ON DELETE RESTRICT (i.e. prevent deleting an object if it has child records)

  • ON DELETE SET NULL (i.e. don't delete a child record, but set it's parent key to NULL instead to break the relationship)

  • Update other related data when a record is deleted (e.g. deleting an uploaded image file)

The following are the potential ways to achieve these that I am aware of:

  • Override the model's delete() method. While this sort of works, it is sidestepped when the records are deleted via a QuerySet. Also, every model's delete() must be overridden to make sure Django's code is never called and super() can't be called as it may use a QuerySet to delete child objects.

  • Use signals. This seems to be ideal as they are called when directly deleting the model or deleting via a QuerySet. However, there is no possibility to prevent a child object from being deleted so it is not usable to implement ON CASCADE RESTRICT or SET NULL.

  • Use a database engine that handles this properly (what does Django do in this case?)

  • Wait until Django supports it (and live with bugs until then...)

It seems like the first option is the only viable one, but it's ugly, throws the baby out with the bath water, and risks missing something when a new model/relation is added.

Am I missing something? Any recommendations?

© Stack Overflow or respective owner

Related posts about django

Related posts about django-signals