我对 Django 很熟悉,但我最近注意到存在一个on_delete=models.CASCADE
与模型的选项。我已经搜索了相同的文档,但除了以下内容之外我找不到任何内容:
Django 1.9 中的更改:
on_delete
现在可以用作第二个位置参数(以前它通常仅作为关键字参数传递)。它将成为 Django 2.0 中的必需参数。
使用示例是 https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.ForeignKey:
from django.db import models
class Car(models.Model):
manufacturer = models.ForeignKey(
'Manufacturer',
on_delete=models.CASCADE,
)
# ...
class Manufacturer(models.Model):
# ...
pass
on_delete 的作用是什么? (我猜如果模型被删除,要执行的操作.)
什么是models.CASCADE
do? (文档中的任何提示)
还有哪些其他可用选项(如果我的猜测是正确的)?
这方面的文档位于哪里?
这是当引用的对象被删除。它不是 Django 特有的;这是一个 SQL 标准。尽管 Django 在 SQL 之上有自己的实现。(1)
发生此类事件时,可以采取七种可能的操作:
-
CASCADE
:当引用的对象被删除时,也删除引用它的对象(例如,当您删除博客文章时,您可能还想删除评论)。 SQL 等效项:CASCADE
.
-
PROTECT
:禁止删除引用的对象。要删除它,您必须手动删除引用它的所有对象。 SQL 等效项:RESTRICT
.
-
RESTRICT
: (Django 3.1中引入)类似的行为PROTECT
匹配 SQL 的RESTRICT
更精确地。 (看Django 文档示例 https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.RESTRICT)
-
SET_NULL
:将引用设置为NULL(要求字段可为空)。例如,当您删除用户时,您可能希望保留他在博客文章上发布的评论,但说它是由匿名(或已删除)用户发布的。 SQL 等效项:SET NULL
.
-
SET_DEFAULT
:设置默认值。 SQL 等效项:SET DEFAULT
.
-
SET(...)
:设置给定值。这不是 SQL 标准的一部分,完全由 Django 处理。
-
DO_NOTHING
:可能是一个非常糟糕的主意,因为这会在数据库中产生完整性问题(引用实际上不存在的对象)。 SQL 等效项:NO ACTION
. (2)
Source: Django 文档 https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.ForeignKey.on_delete
也可以看看PostgreSQL 的文档 https://www.postgresql.org/docs/current/static/sql-createtable.html例如。
在多数情况下,CASCADE
是预期的行为,但对于每个外键,您应该始终问自己在这种情况下预期的行为是什么。PROTECT
and SET_NULL
通常很有用。环境CASCADE
如果不应该,则可以通过简单地删除单个用户来级联删除所有数据库。
澄清级联方向的附加说明
有趣的是注意到CASCADE
行动对于很多人来说并不清楚。事实上,注意到这一点很有趣only the CASCADE
行动不明确。我知道级联行为可能会令人困惑,但是您必须认为它与任何其他动作的方向相同。因此,如果你觉得CASCADE
你不清楚方向,它实际上意味着on_delete
您不清楚行为。
在数据库中,外键基本上由整数字段表示,其值是外对象的主键。假设您有一个条目评论_A,它有一个条目的外键文章_B。如果删除该条目评论_A, 一切安好。文章_B曾经生活在没有评论_A如果它被删除了,也不必担心。但是,如果您删除文章_B, then 评论_A恐慌!它从来没有没有过文章_B并且需要它,它是其属性的一部分(article=article_B
,但是什么是文章_B???)。这是哪里on_delete
采取步骤,确定如何解决此问题完整性错误,或者说:
-
“不!求你了!不要!没有你我活不下去!”(据说
PROTECT
or RESTRICT
在 Django/SQL 中)
-
“好吧,如果我不是你的,那么我就不是任何人的”(据说
SET_NULL
)
-
“再见世界,没有B条我就活不下去”并自杀(这是
CASCADE
行为)。
-
“没关系,我有闲人了,以后就参考文章_C了” (
SET_DEFAULT
, 甚至SET(...)
).
-
“我无法面对现实,我会一直呼唤你的名字,哪怕这是我唯一的事情!” (
DO_NOTHING
)
我希望它能让级联方向更加清晰。 :)
脚注
(1)Django 在 SQL 之上有自己的实现。并作为@JoeMjr2 在下面的评论中提到 https://stackoverflow.com/questions/38388423/what-does-on-delete-do-on-django-models/38389488#comment107117244_38389488,Django不会创建SQL约束。如果您希望数据库确保这些约束(例如,如果您的数据库被其他应用程序使用,或者您不时挂在数据库控制台中),您可能需要自己手动设置相关约束。有一张不限票 https://code.djangoproject.com/ticket/21961在 Django 中添加对数据库级删除约束的支持。
(2)其实,有一种情况,DO_NOTHING
可能有用:如果您想跳过 Django 的实现并在数据库级别自行实现约束。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)