Django 没有设置 MySQL ON DELETE = CASCADE

Posted

技术标签:

【中文标题】Django 没有设置 MySQL ON DELETE = CASCADE【英文标题】:Django not setting MySQL ON DELETE = CASCADE 【发布时间】:2018-12-01 15:56:18 【问题描述】:

我正在使用带有 mysql 5.5 数据库后端的 Django 1.3。我的假设是 Django 在通过 syncdb 构建数据库时默认模拟相关对象的 ON DELETE CASCADE 效果。但是,检查数据库会发现 ON DELETE 属性实际上设置为“RESTRICT”。这是一个错误吗?由于我无法删除相关记录,因此在删除具有相关对象的对象时,我不断在 djang-admin 中收到 IntegrityError 消息。

谢谢

【问题讨论】:

你说的是对的。 Django 模拟 ON DELETE CASCADE。它不使用您的 DBMS 的此功能。 Django 将发出必要的删除语句来删除相关模型。不知道为什么您会在管理员中看到该问题。 【参考方案1】:

Django emulates ON DELETE CASCADE in Python -- 这就是为什么不需要在数据库表上设置它的原因。事实上,设置 RESTRICT 甚至可能是有意义的,因为这意味着您不会在没有在管理员中收到警告的情况下意外删除任何相关对象。

在您的情况下,您似乎设置了 Django 不知道的外键约束——或者您可能正试图通过原始 SQL 删除;从你的问题我看不出来。

如果问题是您无法从管理员或 ORM 中删除,那么您需要确保您的模型定义正确。 django 将负责收集相关对象并自行执行级联。

如果问题是在原始 SQL 中删除不起作用,那么您需要先手动删除相关对象,或者放松 SQL 约束——在这种情况下,将其更改为级联可能是正确的解决方案.

【讨论】:

也许自从这篇评论以来事情已经发生了变化,但是使用 Django 1.9,约束肯定是在创建而不是模拟的,并且是在没有应用级联的情况下创建的。【参考方案2】:

似乎 Django 1.3.1 出于某种原因未能将 ON DELETE CASCADE 属性应用于表。它可能与在 Windows 上运行的 MySQL-python 1.2.3 接口有关。解决此问题的唯一其他方法是通过custom SQL。

【讨论】:

【参考方案3】:

Django 默认是级联的。我不太确定您为什么会收到 ON DELETE RESTRICT。 Django 1.3 确实允许您选择备用 ON DELETE 过程(在定义字段时使用 on_delete kwarg),并且如果您继承了代码库,则可能有人之前已经这样做了,然后从代码中删除了它,但忽略了更新数据库。

我建议手动更改该列以将其设置回 ON DELETE CASCADE。然后从那里继续前进。就像我说的,这是开发人员必须告诉 Django 不要做的事情;它默认是级联的。

【讨论】:

这是我自己的代码库,我从来没有将 on_delete 选项设置为 CASCADE 以外的任何选项。我运行了 python manage.py sql app_name 命令并注意到没有对 ON DELETE CASCADE 的引用。发生了一些奇怪的事情,我只是不知道它是什么。

以上是关于Django 没有设置 MySQL ON DELETE = CASCADE的主要内容,如果未能解决你的问题,请参考以下文章

登录后 Django 引导用户

我如何在 Django 中查询评论

django 在 SQL Server 中指定列排列

在 Django 中的 MySQL 数据库(Navicat Premium)中记录了奇怪的“on”类型

Django2.0 models中的on_delete参数

Mysql设置了 ON UPDATE CURRENT_TIMESTAMP,为什么没有更新