[Solved]-Why does Django do cascading deletes on foreign keys?


7 Years ago…

a Ticket was open #7539

Where it began to be discussed.

years ago by benjaoming

Someone requested a discussion… I just had an encounter with this,
and what I lacked was knowing what’s going on with regards to
cascading deletion, because it’s quite dangerous (you loose data!!)
and steals lots of time. Preventing it is simple, though. Overriding
the delete() method of a model and calling clear() on the related
model’s foreign keys is simple, and it’s a manual implementation, that
all programmers should be able to understand. But I can think of
another alternative: If null=True for the foreign key in question, why
not automatically use SET NULL when the related instance is deleted?
For me, this is even more “intuitive” than CASCADE. After all,
null=True is something that the programmer specifies and has to deal
with anywhere in the implementation, which is also why he doesn’t need
cascading deletion of such a relation. Also, if on_delete is possible
to set in a key field, it would have to comply with the null option..
and together with the “intuition argument” that creates a 1:1
correspondence between the two options. And then the “logic argument”:
Django handles its logic in Python code, not in the Database, which is
kept as a simple storage engine. The RESTRICT option is a validation
issue, and will probably be handled this way in most cases, so having
the database enforcing it, would be redundant. To enable it on
model-level could pave the way for some nice new automatic validation
in ModelForms, so I think it sounds like a nice feature. If all this
is implemented, I would suggest to remove the null option from key
fields and have it set according to on_delete.

Years later, the matter was again discussed in the group.

Django developers (Contributions to Django itself)
changing the on_delete=CASCADE default

And then other tickets were created #21127 and #21961.

And we got here.
ForeignKey and OneToOneField on_delete argument

In order to increase awareness about cascading model deletion, the
on_delete argument of ForeignKey and OneToOneField will be required in
Django 2.0.

Update models and existing migrations to explicitly set the argument.
Since the default is models.CASCADE, add on_delete=models.CASCADE to
all ForeignKey and OneToOneFields that don’t use a different option.
You can also pass it as the second positional argument if you don’t
care about compatibility with older versions of Django.


There is a fairly lengthy discussion on this in this ticket. In Django 2.0 the on_delete argument will be required so the current default behaviour will no longer apply.

Leave a comment