Función del parámetro On_delete en modelos Django
-
Argumento
CASCADE
-
Argumento
PROTECT
-
Argumento
RESTRICT
-
Argumento
SET_NULL
-
Argumento
SET_DEFAULT
-
SET()
Argumento -
Argumento
DO_NOTHING
Los modelos Django simplifican la creación de bases de datos y tablas, agregando nuevos datos o tuplas a las tablas, eliminando, recuperando y modificando. Con los modelos de Django, podemos configurar fácilmente relaciones entre tablas con la ayuda de claves externas.
Al configurar relaciones, tenemos que establecer valores para algunos parámetros. Uno de esos parámetros es on_delete
. El parámetro on_delete
se utiliza para configurar el comportamiento que debe adoptarse cuando se elimina un objeto referenciado. Básicamente se utiliza para definir cómo se manejarán los efectos de la eliminación de un objeto referenciado.
Hay siete posibles comportamientos o acciones para las que se puede configurar el parámetro on_delete
. Hablaremos de todos ellos individualmente.
Argumento CASCADE
El comportamiento en cascada se utiliza generalmente al establecer relaciones entre modelos. Cuando se elimina un objeto al que se hace referencia, también se eliminarán todos los objetos que hacen referencia a ese objeto al que se hace referencia.
Sintaxis
XYZ = models.ForeignKey(WASD, on_delete=models.CASCADE)
Para entenderlo un poco mejor, considere el siguiente ejemplo. Tenga en cuenta que también se utilizará el mismo ejemplo para explicar algunos otros comportamientos.
Existe un sitio web donde los autores pueden registrarse y escribir blogs en el sitio web. Ahora, para representar las dos entidades, considere dos modelos, a saber, Author
y Blog
. Todas las entradas o tuplas en Blog
tienen una referencia de clave externa (o hacen referencia) a una entrada o tupla de Author
. Representa una relación en la que cada blog que se escribe pertenece a un autor que lo escribió.
Ahora, digamos que el sitio web tiene una política según la cual si un autor elimina su cuenta, se eliminarán todos los blogs que haya escrito. En tal escenario, una relación en cascada será una opción adecuada.
Argumento PROTECT
El argumento PROTEGER
evita la eliminación del objeto referenciado si hay objetos que hacen referencia a este objeto. En otras palabras, el objeto al que se hace referencia no se puede eliminar mientras existan objetos que hagan referencia a él. Los objetos de referencia deben eliminarse manualmente antes de eliminar el objeto de referencia. La eliminación se evita generando un ProtectedError
.
Esta relación se puede utilizar en lugares donde los datos son muy importantes y sensibles, y no puede permitirse perderlos con un manejo adecuado. O cuando los objetos de referencia también se están utilizando en otro lugar y no se pueden eliminar sin la validación y el manejo adecuados.
Argumento RESTRICT
RESTRICT
es similar a PROTECT
. También evita la eliminación de objetos referenciados y genera un RestrictedError
. Pero hay una ligera diferencia entre los dos. A diferencia de PROTECT
, si el objeto referenciado hace referencia a algún otro objeto es una relación CASCADE
, y también se está eliminando, entonces se permite la eliminación. En otras palabras, se permite la eliminación del objeto referenciado si los objetos referenciados y el objeto referenciado hacen referencia a algún otro objeto común en una relación “CASCADA”.
Considere el siguiente ejemplo.
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)
Si intentamos eliminar un objeto Album
, se generará RestrictedError
. Pero si tratamos de eliminar un objeto Artist
, la eliminación será exitosa, dado que las canciones que hacen referencia a un objeto Album
también hacen referencia al objeto Artist
al que hace referencia el objeto Album
en una relationship
CASCADA.
Argumento SET_NULL
En el caso de SET_NULL
, como sugiere el nombre, cuando se elimina un objeto referenciado, entonces el objeto referenciado para todos los objetos referenciados se establece en NULL
. Esta relación requiere que el campo del objeto al que se hace referencia sea anulable.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_NULL, null=True)
Por ejemplo, si el sitio web tiene una política de que si un autor se va, sus blogs no se eliminarán. En cambio, el autor de todos los blogs se configurará como autor anónimo o “Ninguno”.
Argumento SET_DEFAULT
En el caso de SET_DEFAULT
, cuando se elimina un objeto referenciado, el objeto referenciado para todos los objetos referenciados se establece en un valor predeterminado. Este valor predeterminado puede ser NULL
así como algún otro modelo o tabla de Django. Esta relación requiere que el campo del objeto referenciado sea anulable en el caso de NULL
.
XYZ = models.ForeignKey(WASD, on_delete=models.SET_DEFAULT, null=True, default=QWERTY)
Por ejemplo, si el sitio web tiene una política de que si un autor se va, el autor de todos sus blogs será el administrador o la propia empresa. En tales casos, SET_DEFAULT
sería la elección correcta.
SET()
Argumento
SET()
es exactamente igual que el de SET_DEFAULT
. También puede aceptar modelos o tablas de Django. La única diferencia es que en SET()
, podemos pasar un invocable, que será llamado para todos los objetos de referencia si se elimina el objeto referenciado.
XYZ = models.ForeignKey(WASD, on_delete=models.SET(...), null=True)
La función invocable, junto con un modelo, se vería así.
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))
Argumento DO_NOTHING
DO_NOTHING
es una relación un poco arriesgada que puede existir entre dos modelos. Como sugiere el nombre, cuando se elimina un objeto referenciado, el objeto referenciado no se cambiará para todos los objetos referenciados. En otras palabras, no se hará nada para manejar los efectos de la eliminación.
Este es un comportamiento muy arriesgado, ya que puede causar problemas de integridad porque el objeto al que se hace referencia se elimina, pero los objetos de referencia todavía lo hacen.
XYZ = models.ForeignKey(WASD, on_delete=models.DO_NOTHING)