36

I'm quite familiar with Django, but recently noticed there exists a on_delete=models.CASCADE and on_delete=models.PROTECT options with the models,

  • on_delete=models.CASCADE and on_delete=models.PROTECT both are doing same things.
  • Or both are same (I used the only on_delete=models.CASCADE, when I remove the parent entry it will remove all related entries )

    I have searched for the documentation for the same but couldn't find anything more than:

Django 2.0

A many-to-one relationship. Requires two positional arguments: the class to which the model is related and the on_delete option. To create a recursive relationship – an object that has a many-to-one relationship with itself – use models.ForeignKey('self', on_delete=models.CASCADE).

GileBrt
  • 1,830
  • 3
  • 20
  • 28
Mr Singh
  • 3,936
  • 5
  • 41
  • 60
  • Does this answer your question? [What does on\_delete do on Django models?](https://stackoverflow.com/questions/38388423/what-does-on-delete-do-on-django-models) – Antoine Pinsard Sep 28 '20 at 10:28
  • [A very detailed and well explained answer to this question is at this link within stack overflow.](https://stackoverflow.com/questions/38388423/what-does-on-delete-do-on-django-models) – Jordan Akpoborie Mar 25 '21 at 09:25
  • See also: [SQL ON DELETE CASCADE, Which Way Does the Deletion Occur?](https://stackoverflow.com/a/74781951/562769) – Martin Thoma Dec 13 '22 at 09:38

2 Answers2

61
  • CASCADE Cascade deletes. Django emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey.

  • PROTECT Prevent deletion of the referenced object by raising ProtectedError, a subclass of django.db.IntegrityError.

the things get deleted because once you change your model you need to do makemigrations and migrate to see the change.

Exprator
  • 26,992
  • 6
  • 47
  • 59
  • Which is the better option to maintain the behavior before Django 2.0, and that won't crash the application? Thanks, – caot Jul 03 '19 at 13:17
  • 9
    this medium post has a very clear explanation: https://medium.com/@inem.patrick/django-database-integrity-foreignkey-on-delete-option-db7d160762e4 – John Q Mar 21 '20 at 20:42
  • if CASCADE "emulates" the SQL constraint of CASCADE.. what does the PROTECT do? I'm not familiar with that constraint type... and even more confused on why a migration is required when using PROTECT – dangel Sep 24 '22 at 01:41
24

For on_delete=models.CASCADE:

You have 2 models i.e., Car and Company. You delete the company, you also delete the cars made by that company.

For on_delete=models.PROTECT:

You have 2 models. Car and Company. You delete the company, Django says, Hold up. Can't do it ... So everything remains.

Here's what you'll see.enter image description here

Mujeeb Ishaque
  • 2,259
  • 24
  • 16
  • If you set `on_delete=Cascade`, and then delete Car, will it delete the company? Asking because it is not clear for me from the documentation – euh Jun 07 '22 at 15:12
  • 1
    @Zhenia it only works in one direction: You have a Company, and you have a Car. Car has a manufacturer. Like this: `manufacturer = ForeignKey(to=Company, models.CASCADE)`. So if you delete a Company, manufacturer will become non-existent, so the car will be deleted too. But if you delete a Car, nothing happens with company: it just doesn't have any links to the car which require some resolving (like casacade deleting or setting it to null) – Pavel Shishmarev Jul 15 '22 at 12:26
  • 2
    @Zhenia in other words, `on_delete` function is the way Django handles links that become invalid because the linked object is deleted. But if you delete the Car, it doesn't affect a company as it doesn't link to the car. – Pavel Shishmarev Jul 15 '22 at 12:30