一尘不染

on_delete对Django模型有什么作用?

django

我对Django非常熟悉,但是最近发现on_delete=models.CASCADE模型中存在一个选项,我在文档中搜索了相同的选项,但找不到以下内容:

在Django 1.9中进行了更改:

on_delete现在可以用作第二个位置参数(以前通常只作为关键字参数传递)。在Django 2.0中,这是必填参数。

使用的一个例子是

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办?(文档中的任何提示)

还有其他可用的选项(如果我的猜测是正确的)?

有关此文档的位置在哪里?


阅读 450

收藏
2020-03-27

共1个答案

一尘不染

这是删除引用对象时采取的行为。它不是特定于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)

我希望它使级联方向更清晰。:)

2020-03-27