Есть ли другой вариант для 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: УстановитеForeignKeynull; это возможно, только если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 к полю базы данных.