¿Por qué la propiedad on_delete de una ForeignKey en un modelo Django no es la predeterminada? Ese debería ser el caso si no hay otra opción que no sean models.CASCADE . ¿Hay alguna otra opción para la propiedad on_delete ?
Sí, hay varios controladores integrados para el parámetro on_delete=… [Django-doc] . La documentación especifica:
CASCADEcascada. Django emula el comportamiento de la restricción SQLON DELETE CASCADEy también elimina el objeto que contieneForeignKey. (…)
PROTECT: evita la eliminación del objeto al que se hace referencia generandoProtectedError, una subclase dedjango.db.IntegrityError.
RESTRICT: evita la eliminación del objeto al que se hace referencia generandoRestrictedError(una subclase dedjango.db.IntegrityError). A diferencia dePROTECT, se permite la eliminación del objeto al que se hace referencia si también hace referencia a un objeto diferente que se está eliminando en la misma operación, pero a través de una relación CASCADA. (…)
SET_NULL: Establecer elForeignKeynull; esto solo es posible sinullesTrue.
SET_DEFAULT: EstableceForeignKeyen su valor predeterminado; se debe establecer undefaultpara ForeignKey.
SET(…): estableceForeignKeyen el valor pasado aSET(), o si se pasa un invocable, el resultado de llamarlo. (…)
DO_NOTHING: No realizar ninguna acción. Si el backend de su base de datos exige integridad referencial, esto provocará un IntegrityError a menos que agregue manualmente una restricción SQLON DELETEal campo de la base de datos.
Además, también puede escribir su propio controlador para el parámetro on_delete=… . Por ejemplo, en este artículo , analizo la implementación de un controlador que, en cierta medida, es lo mismo que un SET(…) pero el invocable que usa acepta como parámetro el objeto que debe actualizarse.
En los "primeros días", django-1.8 y anteriores, no tenía que establecer un parámetro on_delete=… : CASCADE se usaba como valor predeterminado. Pero esto hace que sea bastante implícito lo que debería suceder en caso de que se elimine el objeto al que se hace referencia, por lo que luego hicieron que el parámetro fuera obligatorio.
Los saqué de la documentación de djangos aquí: https://docs.djangoproject.com/en/4.0/ref/models/fields/#foreignkey
También tienen ejemplos de código.
Los valores posibles para on_delete se encuentran en django.db.models:
CASCADE Elimina en cascada. Django emula el comportamiento de la restricción SQL ON DELETE CASCADE y también elimina el objeto que contiene ForeignKey.
Model.delete() no se llama en modelos relacionados, pero las señales pre_delete y post_delete se envían para todos los objetos eliminados.
PROTEGER Evite la eliminación del objeto al que se hace referencia generando ProtectedError, una subclase de django.db.IntegrityError.
RESTRICT Evite la eliminación del objeto al que se hace referencia generando RestrictedError (una subclase de django.db.IntegrityError). A diferencia de PROTECT, se permite la eliminación del objeto al que se hace referencia si también hace referencia a un objeto diferente que se está eliminando en la misma operación, pero a través de una relación CASCADA.
SET_DEFAULT Establece ForeignKey en su valor predeterminado; se debe establecer un valor predeterminado para ForeignKey.
SET() Establece ForeignKey en el valor pasado a SET(), o si se pasa un invocable, el resultado de llamarlo. En la mayoría de los casos, será necesario pasar un invocable para evitar ejecutar consultas en el momento en que se importe su models.py:
DO_NOTHING No realizar ninguna acción. Si el backend de su base de datos impone la integridad referencial, esto provocará un IntegrityError a menos que agregue manualmente una restricción SQL ON DELETE al campo de la base de datos.