Based on the real world applications requirement, we use both for different purpose.
PROTECT never deletes and raises error. But, RESTRICT (introduced from Django 3.1) deletes in some cases, not all.
PROTECT
example:
According to how to prevent deletion,
class Employee(models.Model):
name = models.CharField(name, unique=True)
class Project(models.Model):
name = models.CharField(name, unique=True)
employees = models.ForeignKey(Employee, on_delete=models.PROTECT)
PROTECT
explanation: Think from real worlds perspective. There will be many Employee
s and an Employee
can have multiple Project
s. If we delete an Employee
if he has multiple Project
s associated with it, the project objects in Project
model will be remained. This is wrong. If Employee
has done any Project
s, he (Employee
object) can't be deleted. Hence we used PROTECT
. This would work to prevent the deletion of any Employee object that has one or more Project object(s) associated with it.
You need to understand CASCADE
first before understanding RESTRICT
:
CASCADE
example:
class Artist(models.Model):
name = models.CharField(max_length=10)
class Album(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
CASCADE
explanation: Think from real worlds perspective. There will be many Artist
s and an Artist
can have multiple Album
s. If we want to delete an Artist
and his/her related Album
s, we will use CASCADE
. Remember, CASCADE
deletes. It always deletes.
RESTRICT
example:
class Artist(models.Model):
name = models.CharField(max_length=10)
class Album(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
class Song(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
album = models.ForeignKey(Album, on_delete=models.RESTRICT)
RESTRICT
explanation: Now, think once again from the real world perspective. An Artist
will have zero or more Album
s. An Album
can have zero or more Song
s. There is no problem in deleting if an Artist
have zero Album
s and an Album
have zero Song
s. In fact, there is no relation since Artist
doesn't have any Album
s at all.
The deletion problem arises and the scenario starts when an Artist
has multiple Album
s and an Album
has multiple Song
s. Here's how:
RESTRICT
and PROTECT
works the same way.
But, PROTECT is of two steps. Parent and Child. If we shouldn't delete a Child (Album
), we shouldn't delete a Parent (Artist
). In other words, we use PROTECT
if we don't want our Child (Album
) deleted if Parent(Artist
) deleted. PROTECT
protects from deletion of objects.
And, RESTRICT
is of three steps. Parent and Child and Grand Child. RESTRICT
(a limiting condition or measure) only restricts from deletion of objects up to a certain limit.
You need to understand a real world scenario why we use RESTRICT
.
Lets say there are multiple Artist
s. Each Artist
s have multiple Album
s. Each Album
has multiple song
s. see the below code
>>> artist_one = Artist.objects.create(name='artist one')
>>> artist_two = Artist.objects.create(name='artist two')
>>> album_one = Album.objects.create(artist=artist_one)
>>> album_two = Album.objects.create(artist=artist_two)
>>> song_one = Song.objects.create(artist=artist_one, album=album_one)
>>> song_two = Song.objects.create(artist=artist_one, album=album_two)
>>> album_one.delete()
# Raises RestrictedError.
>>> artist_two.delete()
# Raises RestrictedError.
>>> artist_one.delete()
(4, {'Song': 2, 'Album': 1, 'Artist': 1})
Note that, from above code,
song_one
and song_two
are from same Artist
and different Album
s from different Artist
s.
- One
song
can be sung/written/shared by one or more Artist
s as well.
- One
Song
can be in many Album
s sung/written by one or more Artist
s.
- One
Album
contains many Song
s sung/written by different Artist
s.
How RESTRICTS
works:
Now, in real world, if we have to delete the Artist
all his Album
s and Song
s in Album
s should be deleted. But, only when all the songs in his Album
s doesn't share relationship with other artist
s. In other words, when all songs referenced to the same Artist
, then deletion of Artist
, Album
s and Song
s will happen.
Note that we can't delete artist_two
, because song_two
shared his album_two
along with artist_one
.
In simple words, in Song object, if artist
and artist
from the album are same, RESTRICT allows to delete.