Possible source of cascade deletion on Django 1.9 project?

Viewed 32

I'm working on a Django 1.9 project with a huge source and lots of is inherited from previous developers.

When I delete a User object from the shell there are many other related objects that get deleted as well. I get a print output with a Tuple containing: (# of deleted objects, {u'CLASS_NAME': #number of deleted objects...})

I've searched all the code throughly and there are no Signals attached to User pre_ post_ or on_ delete, neither I can find where this print output is constructed... so, I have no idea where this is coming from.

Any ideas for other possible ways this can be happening?

1 Answers

A ForeignKey [Django-doc] has an on_delete=… parameter. Prior to , you did not have to state this explicitly, in that case it used uses CASCADE, as is specified in the documentation:

on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.

This thus means that if you did not specify an on_delete=… parameter, or you specified this as CASCADE, then if the target record is removed, that model record is removed as well.

You can specify another handler for this. In fact you can even write your own handler, but unless you have to do something very sophisticated, the builtin handlers will likely be sufficient, you can choose between:

  1. CASCADE
  2. PROTECT
  3. SET_NULL
  4. SET_DEFAULT
  5. SET(…)
  6. DO_NOTHING

There are basically four categories: a cascade (CASCADE), prevent the removal (PROTECT), set it to another value (SET_NULL, SET_DEFAULT, SET(…), and DO_NOTHING.

DO_NOTHING is often not a good idea, since most databases enforce referential integrity and will thus refuse to update/delete, since then the foreign key column no longer points to a valid record. By SET_NULL, the field needs to be NULLable (so null=True), you can also set t to a different view.

You should thus pick the strategy that you think is the best, and then the ForeignKey looks like:

class MyModel(models.Model):
    my_field = models.ForeignKey(OtherModel, null=True, on_delete=models.SET_NULL)
Related