这是删除引用对象时采取的行为。它不是特定于Django的,这是一种SQL标准。
发生此类事件时,有6种可能的操作:
CASCADE
:删除引用的对象时,还请删除对其具有引用的对象(例如,删除博客文章时,你可能还希望删除注释)。SQL等效项:CASCADE。PROTECT
:禁止删除引用的对象。要删除它,你将必须删除所有手动引用它的对象。SQL等效项:RESTRICT。SET_NULL
:将引用设置为NULL(要求该字段可为空)。例如,当你删除用户时,你可能希望保留他在博客文章中发布的评论,但说该评论是由匿名(或已删除)用户发布的。SQL等效项:SET NULL。SET_DEFAULT
:设置默认值。SQL等效项:SET DEFAULT。SET(...)
:设置给定值。这不是SQL标准的一部分,完全由Django处理。DO_NOTHING
:这可能是一个非常糟糕的主意,因为这会在数据库中创建完整性问题(引用实际上不存在的对象)。SQL等效项:NO ACTION
。
例如,另请参阅PostGreSQL文档。
在大多数情况下,这
CASCADE是预期的行为,但是对于每个ForeignKey,你应始终问自己在这种情况下的预期行为是什么。
PROTECT并且SET_NULL通常很有用。设置CASCADE不应该设置的位置,可以通过简单地删除单个用户来级联删除所有数据库。
附加说明以阐明级联方向
有趣的是,注意到
CASCADE行动的方向对于许多人来说并不明确。事实上,这很有趣地看到,只有该CASCADE行动并不清楚。我知道级联行为可能会造成混淆,但是你必须认为它与任何其他动作是同一方向。因此,如果你觉得自己CASCADE不清楚方向,那实际上意味着
on_delete你不清楚自己的行为。
在你的数据库中,外键基本上由一个整数字段表示,该值是外对象的主键。假设你有一个comment_A条目,该条目具有一个article_B条目的外键。如果你删除条目comment_A,那么一切都很好,article_B以前可以不带有comment_A生存,并且也不会被删除。但是,如果删除
article_B,则
comment_A会慌!它永远都离不开article_B并需要它,它是它属性的一部分(
article=article_B,但是 article_B * ???)。这是
on_delete确定如何解决此完整性错误的步骤,或者说:
- “No! Please! Don’t! I can’t live without you!” (which is said PROTECT in SQL language)
- “Alright, if I’m not yours, then I’m nobody’s” (which is said SET_NULL)
- “Good bye world, I can’t live without article_B” and commit suicide (this is the CASCADE behavior).
- “It’s OK, I’ve got spare lover, I’ll reference article_C from now” (SET_DEFAULT, or even SET(…)).
- “I can’t face reality, I’ll keep calling your name even if that’s the only thing left to me!” (DO_NOTHING)
我希望它使级联方向更清晰。:)



