Есть ли другой вариант для on_delete, кроме models.CASCADE для ForeignKey в моделях Django?
Почему свойство on_delete
ForeignKey в модели Django не является дефолтным? Это должно быть так, если нет другого варианта, кроме models.CASCADE
. Есть ли другой вариант для свойства on_delete
?
Да, существует несколько встроенных обработчиков для параметра on_delete=…
[Django-doc]. В документации указано:
CASCADE
Каскадные удаления. Django эмулирует поведение SQL ограниченияON DELETE CASCADE
и также удаляет объект содержащийForeignKey
. (...)
PROTECT
: Предотвратить удаление объекта, на который ссылаются, поднявProtectedError
, подклассdjango.db.IntegrityError
.
RESTRICT
: Предотвратить удаление объекта, на который ссылаются, путем поднятияRestrictedError
(подклассdjango.db.IntegrityError
). В отличие отPROTECT
, удаление ссылающегося объекта разрешено, если он также ссылается на другой объект, который удаляется в той же самой операции операции, но через отношение CASCADE. (...)
SET_NULL
: УстановитеForeignKey
null
; это возможно, только еслиnull
являетсяTrue
.
SET_DEFAULT
: УстановитеForeignKey
в значение по умолчанию;default
для внешнего ключа должен быть установлен.
SET(…)
: УстановитеForeignKey
в значение, переданное вSET()
, или, если передана вызываемая переменная, результат ее вызова. (...)
DO_NOTHING
: Не предпринимать никаких действий. Если бэкэнд вашей базы данных обеспечивает ссылочную целостность, это приведет к ошибке IntegrityError, если вы не добавите SQL вручную. вручную не добавите SQLON DELETE
ограничение к полю базы данных.
Кроме того, вы можете написать свой собственный обработчик для параметра on_delete=…
. Например, в этой статье я обсуждаю реализацию обработчика, который в некоторой степени похож на SET(…)
, но используемый им callable принимает в качестве параметра объект, который должен быть обновлен.
В "ранние времена", django-1.8 и ранее, вам не нужно было устанавливать параметр on_delete=…
: CASCADE
использовался как значение по умолчанию. Но это делало неявным, что должно произойти в случае удаления объекта, на который ссылаются, поэтому позже параметр сделали обязательным.
Взял это из документации djangos здесь: https://docs.djangoproject.com/en/4.0/ref/models/fields/#foreignkey
У них также есть примеры кода.
Возможные значения для on_delete можно найти в django.db.models:
CASCADE Каскадное удаление. Django эмулирует поведение SQL ограничения ON DELETE CASCADE и также удаляет объект, содержащий ForeignKey.
Model.delete() не вызывается для связанных моделей, но сигналы pre_delete и post_delete посылаются для всех удаленных объектов.
PROTECT Предотвратите удаление объекта, на который ссылается ссылка, вызвав ProtectedError, подкласс django.db.IntegrityError.
RESTRICT Предотвратить удаление объекта, на который ссылается ссылка, вызвав RestrictedError (подкласс django.db.IntegrityError). В отличие от PROTECT, удаление объекта со ссылкой разрешено, если он также ссылается на другой объект, который удаляется в той же операции, но через отношение CASCADE.
SET_DEFAULT Установить для внешнего ключа значение по умолчанию; для внешнего ключа должно быть установлено значение по умолчанию.
SET() Установите ForeignKey на значение, переданное в SET(), или, если передана вызываемая переменная, на результат ее вызова. В большинстве случаев передача callable необходима для того, чтобы избежать выполнения запросов в момент импорта вашего models.py:
DO_NOTHING Не предпринимать никаких действий. Если бэкэнд вашей базы данных обеспечивает ссылочную целостность, это вызовет ошибку целостности, если вы вручную не добавите ограничение SQL ON DELETE к полю базы данных.