Где в Django реализуется каскадная логика on DELETE? (Используется PostgreSQL. )

Мне просто нужно подтверждение для моего понимания на реализация Django на DELETE CASCADE от вас Django экспертов.

согласно официальной документации Django:

когда Django удаляет объект, по умолчанию он эмулирует поведение ограничение SQL на DELETE CASCADE -- другими словами, любые объекты который имел внешние ключи, указывающие на объект, который будет удален будет удалено вместе с он.

слово "эмулировать" подразумевается, что логика on DELETE CASCADE фактически реализована в Django, а не на уровне базы данных? (Я заглянул в свою базу данных, и все таблицы, содержащие внешние ключи, имеют НА УДАЛИТЬ НЕТ ДЕЙСТВИЯ в своих определениях.)

Если мое понимание верно, есть ли способ, которым я могу переместить НА УДАЛИТЬ КАСКАД логика от уровня приложения до уровня базы данных? Я больше ищет правильный способ, а не хак, сделать это. (Примечание: Я использую PostgreSQL в качестве бэкэнда.)

2 ответов


Если вы спрашиваете, где реализуется соответствующий код: вы можете найти его здесь.

реализация логики каскадного удаления в слое application/ORM имеет смысл, поскольку это позволяет приложению получать информацию при удалении (например. Сигналы удаления Django запускаются для удаленных экземпляров), кроме того, это разумный способ включить эту функцию в разных типах баз данных.

Если вы беспокоитесь о целостности ваших данных: Django все еще устанавливает ограничения внешнего ключа, если ваша база данных поддерживает это (например. проверьте Postgresql). Таким образом, ваша база данных не позволит вам удалить строки, на которые указывает внешний ключ.

попробуйте сами:

> DELETE FROM accounts_publisher WHERE id=5;
ERROR:  update or delete on table "accounts_publisher" violates foreign key constraint "accounts_publisher_id_411559b18a178e73_fk_accounts_publisher_id" on table "accounts_membership"
DETAIL:  Key (id)=(5) is still referenced from table "accounts_membership".

FYI, это настраивается с django 1.3: https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ForeignKey.on_delete

в основном вам нужно установить on_delete для DO_NOTHING и добавить каскадную логику в БД самостоятельно:

DO_NOTHING: не предпринимать никаких действий. Если сервер базы данных обеспечивает ссылочную целостность, это вызовет IntegrityError, если вы вручную не добавите ограничение SQL ON DELETE в базу данных поле (возможно, с использованием исходного sql).