我只需要确认一下我对Django专家的 Django实现ON DELETE CASCADE 的理解。
根据官方Django文档:
当Django删除一个对象时,默认情况下它会模拟对象的行为 SQL约束ON DELETE CASCADE - 换句话说,任何对象 有外键指向要删除的对象的将是 随之删除。
单词“模拟”是否意味着ON DELETE CASCADE逻辑实际上是在Django而不是在数据库级别实现的? (我查看了我的数据库,所有包含外键的表在其定义中都有 ON DELETE NO ACTION 。)
如果我的理解是正确的,有什么方法可以将 ON DELETE CASCADE 逻辑从应用层重新定位到数据库层?我正在寻找一种正确的方式,而不是黑客。 (注意:我使用PostgreSQL作为我的后端。)
答案 0 :(得分:7)
如果您询问相关代码的实施位置:您可以找到它here。
在应用程序/ ORM层中实现CASCADE-DELETE逻辑是有意义的,因为这使得应用程序在删除发生时得到通知(例如,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".
答案 1 :(得分:-1)
仅供参考,这是自django 1.3以来可配置的: https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ForeignKey.on_delete
基本上你需要将on_delete设置为DO_NOTHING并自己将级联逻辑添加到DB中:
DO_NOTHING:不采取任何行动。如果数据库后端强制实施参照完整性,除非您手动将SQL ON DELETE约束添加到数据库字段(可能使用初始sql),否则这将导致IntegrityError。