当前位置: 首页 > 知识库问答 >
问题:

on_delete在Django模型上做什么?

隆飞驰
2023-03-14

我对Django非常熟悉,但最近我注意到在模型上有一个选项。我已经搜索了相同的文档,但除了以下内容外,我找不到其他内容:

在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做什么?(文档中的任何提示)

还有什么其他选择(如果我的猜测是正确的)?

这方面的文档存放在哪里?

共有3个答案

轩辕煜
2023-03-14
匿名用户

仅供参考,模型中的on_delete参数与听起来的相反。您在模型的外键(FK)上放置_delete,告诉Django如果您在记录上指向的FK条目被删除,该怎么办。我们商店使用最多的选项是PROTECTCASCADESET\u NULL。以下是我已经弄明白的基本规则:

  1. 使用PROTECT当您的FK指向一个确实不应该更改的查找表,并且肯定不应该导致您的表更改。如果有人试图删除该查找表上的条目,如果该条目绑定到任何记录,PROTECT将阻止他们删除该条目。它还防止Django仅仅因为删除了查找表上的条目而删除您的记录。最后一部分很关键。如果有人从我的性别表中删除性别“女性”,我肯定不希望立即删除我的个人表中所有具有该性别的人。
  2. 使用CASCADE当你的FK指向一个父记录。所以,如果一个人可以有许多人种条目(他/她可以是美国印第安人、黑人和白人),并且那个人被删除了,我真的希望任何“儿童”人种条目被删除。没有人,他们是无关紧要的。
  3. 当您确实希望允许人们删除查找表上的条目,但您仍然希望保留您的记录时,请使用SET_NULL。例如,如果一个人可以拥有高中,但如果高中在我的查找表上消失了,对我来说并不重要,我会说on_delete=SET_NULL。这会把我的个人记录留在那里;这只会把我个人的高中FK设置为零。显然,您必须在该FK上允许null=True

下面是一个模型的例子,它可以做这三件事:

class PurchPurchaseAccount(models.Model):
    id = models.AutoField(primary_key=True)
    purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
    paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
    _updated = models.DateTimeField()
    _updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.

    def __unicode__(self):
        return str(self.paid_from_acct.display)
    class Meta:
        db_table = u'purch_purchase_account'

最后一点,您知道吗,如果您没有在_delete上指定(或未指定),默认行为是级联?这意味着,如果有人删除了您的性别表中的性别条目,则具有该性别的任何个人记录也将被删除!

我会说,“如果有疑问,请在_delete=models.PROTECT上设置”,然后去测试你的应用程序。您将快速确定哪些FK应标记为其他值,而不会危及任何数据。

另外,值得注意的是,如果您选择的是迁移行为,那么实际上没有将on_delete=CASCADE添加到任何迁移中。我想这是因为它是默认设置,所以将放在_delete=CASCADE上与不放任何内容是一样的。

裴翰学
2023-03-14
匿名用户

on_delete方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例。(例如,ForeignKey关系)。_delete=models.CASCADE上的告诉Django级联删除效果,即继续删除依赖模型。

这里有一个更具体的例子。假设您有一个作者模型,它是书籍模型中的外键。现在,如果删除作者模型的实例,Django将不知道如何处理依赖于该作者模型实例的书籍模型的实例。on_delete的方法告诉Django在这种情况下该怎么做。在_delete=models上设置。CASCADE将指示Django级联删除效果,即删除所有依赖于您删除的作者模型实例的书籍模型实例。

注意:on_delete将成为Django 2.0中的必需参数。在旧版本中,它默认为CASCADE

这是整个官方留档。

吕向荣
2023-03-14

这是删除引用对象时要采用的行为。它不是Django特有的;这是一个SQL标准。尽管Django在SQL之上有自己的实现。(1)

发生此类事件时,可采取七种可能的措施:

  • CASCADE:当引用的对象被删除时,也删除引用它的对象(例如,当您删除博客文章时,您可能也想删除评论)。SQL等效的:CASCADE
  • PROTECT:禁止删除引用的对象。要删除它,您必须手动删除所有引用它的对象。SQL等效的:RESTRICT
  • RESTRICT:(在Django 3.1中介绍)类似于PROTECT的行为,更准确地匹配SQL的RESTRICT。(参见django留档示例)
  • SET_NULL:将引用设置为NULL(要求字段可以为空)。例如,当你删除一个用户时,你可能想保留他在博客帖子上发表的评论,但假设它是由一个匿名(或被删除)用户发表的。SQL等同于:SET NULL
  • SET_DEFAULT:设置默认值。SQL等效的:SET DEFAULT
  • SET(...):设置给定的值。这个不是SQL标准的一部分,完全由Django处理。
  • DO_NOTHING:这可能是一个非常糟糕的主意,因为这会在你的数据库中造成完整性问题(引用一个实际上不存在的对象)。SQL等效的:NO ACTION。(2)

来源:Django留档

例如,另请参见PostgreSQL的文档。

在大多数情况下,CASCADE是预期的行为,但对于每一位外籍钥匙,您应该始终问自己在这种情况下预期的行为是什么<代码>保护和设置为空通常很有用。如果设置CASCADE,则只需删除一个用户,就可以删除CASCADE中的所有数据库。

澄清叶栅方向的补充说明

有趣的是,许多人不清楚CASCADE操作的方向。实际上,有趣的是,只有CASCADE操作不清晰。我知道级联行为可能会令人困惑,但是您必须认为它与任何其他操作是相同的方向。因此,如果你觉得CASCADE方向对你来说不清楚,这实际上意味着on_delete行为对你来说不清楚。

在数据库中,外键基本上由一个整型字段表示,该字段的值是外部对象的主键。假设你有一个条目注释A,它有一个条目文章B的外键。如果你删除条目注释A,一切正常。文章B过去没有评论过,如果被删除了也不用担心。然而,如果你删除了文章B,那么评论A就会恐慌!它从来没有离开过article_B,也需要它,它是它属性的一部分(article=article_B,但是article_B是什么??)。这是删除时的步骤,以确定如何解决此完整性错误,方法如下:

  • “不!请不要!没有你我活不下去!”(在Django/SQL中称为PROTECTRESTRICT

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

脚注

(1) Django在SQL之上有自己的实现。而且,正如@JoeMjr2在下面的评论中提到的,Django不会创建SQL约束。如果希望数据库确保约束(例如,如果数据库被其他应用程序使用,或者如果您不时挂起数据库控制台),则可能需要自己手动设置相关约束。在Django中,有一个开放的票证可以添加对数据库级delete约束的支持。

(2) 实际上,有一种情况下,dou_NOTHING可能很有用:如果您想跳过Django的实现,自己在数据库级别实现约束。

 类似资料:
  • 我对Django非常熟悉,但最近注意到在_delete=models上存在一个和选项, > 我已搜索了相同的文档,但除了以下内容外,找不到其他内容: Django 2.0 多对一的关系。需要两个位置参数:与模型相关的类和on_delete选项。要创建递归关系(一个与自身具有多对一关系的对象),请使用models.ForeignKey('self',on_delete=models.CASCADE)

  • 问题内容: 我对Django非常熟悉,但是最近发现模型中存在一个选项,我在文档中搜索了相同的选项,但找不到以下内容: 在Django 1.9中进行了更改: 现在可以用作第二个位置参数(以前通常只作为关键字参数传递)。在Django 2.0中,这是必填参数。 使用的一个例子是 on_delete是做什么的?(我想如果删除模型,要执行的操作) 怎么办?(文档中的任何提示) 还有其他可用的选项(如果我的

  • 我想修改一个外键值,当它从数据库中删除。所以我看了医生,用on_delete=模型。SET(foo)方法.https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.SET 这是我的模型定义 这是我的方法,被称为删除 然而这里的问题是,我不能将参数传递给这个方法,这就是为什么我不能知道删除了哪个产品。我还试着在

  • 在django模型中使用“on_delete=models.CASCADE”时会发生什么

  • 主要内容:,创建模型,操作数据(CRUD),其他数据操作,,链接模型模型是表示我们的数据库表或集合类,并且其中所述类的每个属性是表或集合的字段。模型是在 app/models.py 中定义(在我们的例子中是:myapp/models.py) 创建模型 下面是创建一个 Dreamreal 模型实例 − 每一个模型继承自django.db.models.Model。 我们类有4个属性(3 CharField和1个整数),这将是表中的字段。 Meta类与db_table

  • 我们现在将要创建的是一个能存储我们博客所有文章的东西。为了达到这个目的,我们将要讲解一下一个被称为objects(对象)的东西. 对象 在编程中有一个概念叫做 面向对象编程 。 它的思想是,与其用无聊的一连串的程序指令方式写程序,我们不如为事物建立模型,然后定义他们是怎样互相交互的。 那什幺是对象呢?它是一个属性和操作的集合。它听起来很奇怪,但我们会给你一个例子。 如果我们想塑造一只猫的模型,我们