Модели Django обычно обрабатывают поведение ON DELETE CASCADE вполне адекватно (таким образом, что это работает с базами данных, которые не поддерживают его изначально).
Тем не менее, я изо всех сил пытаюсь обнаружить, что является лучшим способом переопределить это поведение, когда это не подходит, в следующих сценариях, например:
-
ON DELETE RESTRICT (т.е. удалять объект, если он имеет дочерние записи)
-
ON DELETE SET NULL (т.е. не удалять дочернюю запись, а вместо этого установите родительский ключ в NULL, чтобы разорвать связь)
-
Обновление других связанных данных при удалении записи (например, удаление загруженного файла изображения)
Ниже приводятся возможные способы достижения этих целей, о которых я знаю:
-
Отмените метод модели
delete()
. Несмотря на то, что этот вид работ, он обходит стороной, когда записи удаляются черезQuerySet
. Кроме того, каждая модельdelete()
должна быть переопределена, чтобы убедиться, что код Django никогда не вызывается иsuper()
не может быть вызван, поскольку он может использоватьQuerySet
для удаления дочерних объектов. -
Используйте сигналы. Это кажется идеальным, поскольку они вызываются при прямом удалении модели или удалении через QuerySet. Тем не менее, нет возможности предотвратить удаление дочернего объекта, поэтому его нельзя использовать для ВКЛЮЧЕНА КАСКАДЫ ИЛИ УСТАНОВЛЕННОГО НУЛЬТА.
-
Использовать механизм базы данных, который обрабатывает это правильно (что делает Django в этом случае?)
-
Подождите, пока Django не поддержит его (и будет жить с ошибками до тех пор...)
Кажется, что первый вариант - единственный жизнеспособный, но он уродливый, выкидывает ребенка с водой для ванны и рискует чего-то потерять при добавлении новой модели/отношения.
Я что-то упустил? Любые рекомендации?