我对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
做什么?(文档中的任何提示)
还有什么其他选择(如果我的猜测是正确的)?
这方面的文档存放在哪里?
匿名用户
仅供参考,模型中的on_delete
参数与听起来的相反。您在模型的外键(FK)上放置_delete
,告诉Django如果您在记录上指向的FK条目被删除,该怎么办。我们商店使用最多的选项是PROTECT
、CASCADE
和SET\u NULL
。以下是我已经弄明白的基本规则:
- 使用
PROTECT
当您的FK指向一个确实不应该更改的查找表,并且肯定不应该导致您的表更改。如果有人试图删除该查找表上的条目,如果该条目绑定到任何记录,PROTECT
将阻止他们删除该条目。它还防止Django仅仅因为删除了查找表上的条目而删除您的记录。最后一部分很关键。如果有人从我的性别表中删除性别“女性”,我肯定不希望立即删除我的个人表中所有具有该性别的人。
- 使用
CASCADE
当你的FK指向一个父记录。所以,如果一个人可以有许多人种条目(他/她可以是美国印第安人、黑人和白人),并且那个人被删除了,我真的希望任何“儿童”人种条目被删除。没有人,他们是无关紧要的。
- 当您确实希望允许人们删除查找表上的条目,但您仍然希望保留您的记录时,请使用
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
上与不放任何内容是一样的。
on_delete方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例。(例如,ForeignKey
关系)。_delete=models.CASCADE上的告诉Django级联删除效果,即继续删除依赖模型。
这里有一个更具体的例子。假设您有一个
作者
模型,它是书籍
模型中的外键
。现在,如果删除作者
模型的实例,Django将不知道如何处理依赖于该作者
模型实例的书籍
模型的实例。on_delete的方法告诉Django在这种情况下该怎么做。在_delete=models上设置
。CASCADE
将指示Django级联删除效果,即删除所有依赖于您删除的作者
模型实例的书籍
模型实例。
注意:
on_delete
将成为Django 2.0中的必需参数。在旧版本中,它默认为CASCADE
。
这是整个官方留档。
这是删除引用对象时要采用的行为。它不是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中称为PROTECT
或RESTRICT
)
我希望它使级联方向更清晰。:)
脚注
(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(对象)的东西. 对象 在编程中有一个概念叫做 面向对象编程 。 它的思想是,与其用无聊的一连串的程序指令方式写程序,我们不如为事物建立模型,然后定义他们是怎样互相交互的。 那什幺是对象呢?它是一个属性和操作的集合。它听起来很奇怪,但我们会给你一个例子。 如果我们想塑造一只猫的模型,我们