Есть ли другой вариант для 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 вручную. вручную не добавите SQL ON DELETE ограничение к полю базы данных.

Кроме того, вы можете написать свой собственный обработчик для параметра on_delete=…. Например, в этой статье я обсуждаю реализацию обработчика, который в некоторой степени похож на SET(…), но используемый им callable принимает в качестве параметра объект, который должен быть обновлен.

В "ранние времена", и ранее, вам не нужно было устанавливать параметр 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 к полю базы данных.

Вернуться на верх