Function of On_delete Parameter in Django Models
-
CASCADE
Argument -
PROTECT
Argument -
RESTRICT
Argument -
SET_NULL
Argument -
SET_DEFAULT
Argument -
SET()
Argument -
DO_NOTHING
Argument
Django Models simplify the database and table creation, adding new data or tuples to tables, deleting, retrieval, and modification. With Django models, we can easily set up relationships between tables with the help of foreign keys.
When setting up relationships, we have to set values for a few parameters. One such parameter is the on_delete
. The on_delete
parameter is used to configure the behavior that should be adopted when a referenced object is deleted. It is basically used to define how the effects of the deletion of a referenced object will be handled.
There are seven possible behaviors or actions that the on_delete
parameter can be configured to. We’ll talk about all of them individually.
CASCADE
Argument
The cascading behavior is generally used when setting up relationships between models. When a referenced object is deleted, then all the objects referencing that referenced object will also be deleted.
Syntax
XYZ = models.ForeignKey(WASD, on_delete=models.CASCADE)
To understand it a little better, consider the following example. Note that the same example will be used to explain some other behaviors as well.
There is a website where authors can register themselves and write blogs on the website. Now the represent the two entities, consider two models, namely, Author
and Blog
. All the entries or tuples in Blog
have a foreign key reference (or are referencing) to an Author
entry or tuple. It represents a relationship that every blog is ever written belongs to an author who wrote it.
Now, let say the website has a policy that if an author deletes his/her account, then all the blogs ever written by him or her will be removed. In such a scenario, a cascading relationship will be an apt choice.
PROTECT
Argument
The PROTECT
argument prevents the deletion of the referenced object if there are objects referencing this object. In other words, the referenced object can’t be deleted as long as objects referencing it exists. The referencing objects have to be deleted manually before deleting the referenced object. The deletion is prevented by raising a ProtectedError
.
This relationship can be used at places where data is very important and sensitive, and you can’t afford to lose it with proper handling. Or when the referencing objects are being used somewhere else as well, and they can’t be deleted without proper validation and handling.
RESTRICT
Argument
RESTRICT
is similar to PROTECT
. It also prevents deletion of referenced objects and raises a RestrictedError
. But there is a slight difference between the two. Unlike PROTECT
, if the referenced object is referencing some other object is a CASCADE
relationship, and it is also getting deleted, then the deletion is allowed. In other words, the deletion of the referenced object is allowed if the referencing objects and the referenced object reference some other common object in a CASCADE
relationship.
Consider the following example.
class Artist(models.Model):
name = models.CharField(max_length=100)
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)
If we try to delete an Album
object, RestrictedError
will be raised. But is we try to delete an Artist
object, then the deletion will be successful, given that the songs referencing an Album
object are also referencing the Artist
object referenced by the Album
object in a CASCADE relationship
.
SET_NULL
Argument
In the case of SET_NULL
, as the name suggests, when a referenced object is deleted, then the referenced object for all the referencing objects is set to NULL
. This relationship requires the referenced object field to be nullable.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_NULL, null=True)
For example, if the website has a policy that if an author leaves, then his/her blogs will not but deleted. Instead, the author for all the blogs will be set to an anonymous author or None
.
SET_DEFAULT
Argument
In the case of SET_DEFAULT
, when a referenced object is deleted, then the referenced object for all the referencing objects is set to a default value. This default value can NULL
as well as some other Django model or table. This relationship requires the referenced object field to be nullable in the case of NULL
.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_DEFAULT, null=True, default=QWERTY)
For example, if the website has a policy that if an author leaves, then the author for all his/her blogs will be the admin or the company itself. In such cases, SET_DEFAULT
would be the right choice.
SET()
Argument
SET()
is exactly the same as that of SET_DEFAULT
. It can accept Django models or tables as well. The only difference is that in SET()
, we can pass a callable, which will be called for all the referencing objects if the referenced object is deleted.
XYZ = models.ForeignKey(WASD, on_delete=models.SET(...), null=True)
The callable function, along with a model, would look something like this.
def getUser():
"""Callable function"""
return User.objects.get_or_create(username="anonymous")[0]
class Author(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(getUser))
DO_NOTHING
Argument
DO_NOTHING
is a bit risky relationship that can exist between two models. As the name suggests, when a referenced object is deleted, then the referenced object will not be changed for all the referencing objects. In other words, nothing will be done to handle the effects of deletion.
This is a very risky behavior as it can cause integrity issues because the referenced object is deleted, but the referencing objects are still referencing it.
XYZ = models.ForeignKey(WASD, on_delete=models.DO_NOTHING)