Django's ORM supports the concept of a 'cascade delete' - whereby the deletion of an object via the ORM results in the deletion of its related child object (related via a Foreign Key relationship).
We had an open question re. where to put side-effects that we wanted to run every time an object was deleted, irrespective of whether it was deleted directly, or indirectly as part of of a cascade (i.e. its parent was deleted).
To work it all out, we first of all checked out the Django source code. This suggested that when calling a parent object's
delete method, although child objects are deleted, their individual
delete methods are never called. This had a fairly dramatic impact on our discussion, given that we were discussing putting related clean-up code into the
delete method, so we decided to create a test project to prove the point.
The code is on Github, you can download it and run the tests yourself. If you're too impatient, the summary is that it does exactly what the source suggested - firing the
post_delete signals, but not calling the
The output from (one of) the project tests:
>>> parent = Parent(name=u"Fred")
>>> Child(name=u"Bob", parent=parent).save()
>>> Child(name=u"Gob", parent=parent).save()
>>> Child(name=u"Lob", parent=parent).save()
DEBUG Enter Parent.delete() method.
DEBUG Deleting Child: Bob. # pre_delete signal
DEBUG Deleting Child: Gob.
DEBUG Deleting Child: Lob.
DEBUG Deleting Parent: Fred.
DEBUG Deleted Child: Lob. # post_delete signal
DEBUG Deleted Child: Gob.
DEBUG Deleted Child: Bob.
DEBUG Deleted Parent: Fred.
DEBUG Exit Parent.delete() method.
As ever, clone, edit, submit pull requests - do anything you like - the only thing we'd ask is that if you add anything interesting please submit a pull request and pay it back in to the project for everyone to benefit.