What is on_delete in Django?
When you create a ForeignKey, you must tell Django:
➡️ What should happen to the child object if the parent object is deleted?
Example:
student = models.ForeignKey(Student, on_delete=WHAT_HAPPENS_HERE)
✅ 1. models.CASCADE
Meaning:
If the parent is deleted → delete the child too.
Example:
If Student Rafi is deleted → all of Rafi's Results are also deleted.
When to use?
✔ When child data makes no sense without parent
✔ Example: Results cannot exist without a student
✅ 2. models.SET_NULL
Meaning:
If parent is deleted → set the FK to NULL.
Example
class Student(models.Model):
name = models.CharField(max_length=100)
class Result(models.Model):
student = models.ForeignKey(Student, on_delete=models.SET_NULL)
If Student Rafi is deleted → Result records will stay, but:
student = NULL
When to use?
✔ When child can exist without parent
✔ Example: Blog post author deleted → post remains
✅ 3. models.PROTECT
Meaning:
Prevent deletion of parent if child exists.
Example:
If you try to delete a Student who has results:
❌ Django throws an error: ProtectedError
✔ This stops accidental data loss
When to use?
✔ Very important data
✔ Example: Cannot delete Category that still has products
✅ 4. models.SET_DEFAULT
Meaning:
If parent is deleted → set FK to a default value.
Example:
If the linked student is deleted → student will become ID = 1.
When to use?
✔ Use when you want a fallback
✔ Example: Deleted author → assign to "Unknown Author"
✅ 5. models.DO_NOTHING
Meaning:
Do nothing.
Django won't touch child objects.
BUT ⚠️
If DB has restrictions, you get errors.
Example:
on_delete=models.DO_NOTHING
When to use?
❌ Almost never recommended
✔ Only when you handle deletion manually
✅ 6. models.RESTRICT (Django 3.1+)
Meaning:
Like PROTECT, but safer and more predictable.
If child exists → prevent parent deletion.
Example:
student = models.ForeignKey(Student, on_delete=models.RESTRICT)
When to use?
✔ Use instead of PROTECT
✔ Prevents accidental deletion cleanly
🎯 Summary (Easy to Remember)
| Option | What Happens |
|---|---|
| CASCADE | Delete children |
| SET_NULL | Make FK = NULL |
| SET_DEFAULT | Set default value |
| PROTECT | Block delete (throws error) |
| RESTRICT | Block delete (better than PROTECT) |
| DO_NOTHING | Do nothing (dangerous) |