on_delete在Django模型上做什么?

时间:2021-09-14 10:34:05

I'm quite familiar with Django, but recently noticed there exists a on_delete=models.CASCADE option with the models, I have searched for the documentation for the same but couldn't find anything more than,

我对Django非常熟悉,但是最近注意到存在一个on_delete=模型。使用这些模型的CASCADE选项,我已经搜索了同样的文档但是没有发现更多,

Changed in Django 1.9:

改变了Django 1.9:

on_delete can now be used as the second positional argument (previously it was typically only passed as a keyword argument). It will be a required argument in Django 2.0.

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

an example case of usage is

使用的一个例子是。

from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...

class Manufacturer(models.Model):
    # ...
    pass

What does on_delete does? (guess the actions to be done if the model is deleted)

on_delete做什么?(如果模型被删除,猜测需要执行的操作)

What does models.CASCADE do? (any hints in documentation)

什么模型。级联做什么?(文档中任何提示)

What other options are available (if my guess is correct)?

如果我的猜测是正确的,还有其他的选择吗?

Where does the documentation for this resides?

这个文档位于何处?

3 个解决方案

#1


185  

This is the behaviour to adopt when the referenced object is deleted. It is not specific to django, this is an SQL standard.

这是在删除引用对象时要采用的行为。它不是django特有的,这是一个SQL标准。

There are 6 possible actions to take when such event occurs:

当这类事件发生时,有六种可能的行动:

  • CASCADE: When the referenced object is deleted, also delete the objects that have references to it (When you remove a blog post for instance, you might want to delete comments as well). SQL equivalent: CASCADE.
  • CASCADE:当被引用的对象被删除时,也要删除对它有引用的对象(例如,当你删除一个博客文章时,你可能也想要删除评论)。SQL等效:级联。
  • PROTECT: Forbid the deletion of the referenced object. To delete it you will have to delete all objects that reference it manually. SQL equivalent: RESTRICT.
  • 保护:禁止删除引用的对象。要删除它,您必须删除所有手动引用它的对象。SQL等效:限制。
  • SET_NULL: Set the reference to NULL (requires the field to be nullable). For instance, when you delete a User, you might want to keep the comments he posted on blog posts, but say it was posted by an anonymous (or deleted) user. SQL equivalent: SET NULL.
  • SET_NULL:将引用设置为NULL(要求字段为空)。例如,当您删除一个用户时,您可能希望保留他在博客文章中发布的评论,但您可能会说它是由一个匿名(或已删除)用户发布的。SQL等效:设置为空。
  • SET_DEFAULT: Set the default value. SQL equivalent: SET DEFAULT.
  • SET_DEFAULT:设置默认值。SQL等效:设置默认。
  • SET(...): Set a given value. This one is not part of the SQL standard and is entirely handled by Django.
  • SET(…):设置给定的值。这个不是SQL标准的一部分,完全由Django处理。
  • DO_NOTHING: Probably a very bad idea since this would create integrity issues in your database (referencing an object that actually doesn't exist). SQL equivalent: NO ACTION.
  • DO_NOTHING:这可能是一个非常糟糕的想法,因为这会在数据库中创建完整性问题(引用一个实际上不存在的对象)。SQL等效:不行动。

Source: Django documentation

来源:Django文档

See also the documentation of PostGreSQL for instance.

例如,请参见PostGreSQL的文档。

In most cases, CASCADE is the expected behaviour, but for every ForeignKey, you should always ask yourself what is the expected behaviour in this situation. PROTECT and SET_NULL are often useful. Setting CASCADE where it should not, can potentially delete all your database in cascade, by simply deleting a single user.

在大多数情况下,级联是预期的行为,但是对于每一个外国人来说,你都应该问问自己在这种情况下预期的行为是什么。PROTECT和SET_NULL通常很有用。在不应该设置的地方设置CASCADE,可以通过简单地删除一个用户来潜在地以CASCADE的方式删除所有的数据库。

#2


23  

The on_delete method is used to tell Django what to do with model instances that depend on the model instance you delete. (e.g. a ForeignKey relationship). The on_delete=models.CASCADE tells Django to cascade the deleting effect i.e. continue deleting the dependent models as well.

on_delete方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例。(如ForeignKey关系)。on_delete =模型。CASCADE告诉Django对删除效果进行级联,也就是继续删除相关的模型。

Here's a more concrete example. Assume you have an Author model that is a ForeignKey in a Book model. Now, if you delete an instance of the Author model, Django would not know what to do with instances of the Book model that depend on that instance of Author model. The on_delete method tells Django what to do in that case. Setting on_delete=models.CASCADE will instruct Django to cascade the deleting effect i.e. delete all the Book model instances that depend on the Author model instance you deleted.

这里有一个更具体的例子。假设您有一个作者模型,它是图书模型中的一个外国人。现在,如果删除Author模型的一个实例,Django不知道如何处理依赖于Author模型实例的Book模型实例。on_delete方法告诉Django在这种情况下该做什么。设置on_delete =模型。CASCADE会指示Django对删除效果进行级联,即删除所有依赖于您删除的Author模型实例的Book模型实例。

Note: on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.

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

Here's the entire official documentation.

这是整个官方文件。

#3


10  

FYI, the on_delete parameter in models is backwards from what it sounds like. You put "on_delete" on a Foreign Key (FK) on a model to tell django what to do if the FK entry that you are pointing to on your record is deleted. The options our shop have used the most are PROTECT, CASCADE, and SET_NULL. Here are the basic rules I have figured out:

FYI,模型中的on_delete参数是向后的,听起来就像这样。将“on_delete”放在模型的外键(FK)上,以告知django,如果记录中指向的FK条目被删除,该如何做。我们商店使用最多的选项是PROTECT、CASCADE和SET_NULL。以下是我总结出的基本原则:

  1. Use PROTECT when your FK is pointing to a look-up table that really shouldn't be changing and that certainly should not cause your table to change. If anyone tries to delete an entry on that look-up table, PROTECT prevents them from deleting it if it is tied to any records. It also prevents django from deleting your record just because it deleted an entry on a look-up table. This last part is critical. If someone were to delete the gender "Female" from my Gender table, I CERTAINLY would NOT want that to instantly delete any and all people I had in my Person table who had that gender.
  2. 当您的FK指向一个查找表时,请使用PROTECT,它确实不应该发生更改,也不应该导致您的表发生更改。如果有人试图删除查找表上的一个条目,PROTECT会阻止他们删除与任何记录绑定的条目。它还防止django仅仅因为删除了查找表上的一个条目而删除您的记录。最后这一部分至关重要。如果有人要从我的性别表中删除性别“女性”,我当然不希望它立即删除我的Person表中所有具有该性别的人。
  3. Use CASCADE when your FK is pointing to a "parent" record. So, if a Person can have many PersonEthnicity entries (he/she can be American Indian, Black, and White), and that Person is deleted, I really would want any "child" PersonEthnicity entries to be deleted. They are irrelevant without the Person.
  4. 当您的FK指向“父”记录时,请使用CASCADE。因此,如果一个人可以有许多个人种族条目(他/她可以是美国印第安人、黑人和白人),而这个人被删除,我真的希望删除任何“儿童”个人种族条目。没有人,他们是无关紧要的。
  5. Use SET_NULL when you do want people to be allowed to delete an entry on a look-up table, but you still want to preserve your record. For example, if a Person can have a HighSchool, but it doesn't really matter to me if that high-school goes away on my look-up table, I would say "on_delete=SET_NULL." This would leave my Person record out there; it just would just set the high-school FK on my Person to null. Obviously, you will have to allow null=True on that FK.
  6. 当您确实希望允许人们删除查找表上的一个条目时,请使用SET_NULL,但仍然希望保留记录。例如,如果一个人可以上高中,但是如果那个高中在我的查找表上消失了,我就会说“on_delete=SET_NULL”。这会留下我的个人记录;它只会把我的人的高中FK设为空。显然,在FK上必须允许null=True。

Here is an example of a model that does all three things:

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

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'

As a last tidbit, did you know that if you don't specify on_delete (or didn't), the default behavior is CASCADE? This means that if someone deleted a gender entry on your Gender table, any Person records with that gender were also deleted!

最后,您是否知道如果不指定on_delete(或不指定),默认行为是CASCADE?这意味着如果有人删除了您的性别表上的性别条目,任何具有该性别的人记录也被删除!

I would say, "If in doubt, set on_delete=models.PROTECT." Then go test your application. You will quickly figure out which FKs should be labeled the other values without endangering any of your data.

我会说,“如果有疑问,请设置on_delete=models.PROTECT。”然后去测试你的应用程序。您将很快发现哪些FKs应该被标记为其他值,而不会危及您的任何数据。

Also, it is worth noting that on_delete=CASCADE is actually not added to any of your migrations, if that is the behavior you are selecting. I guess this is because it is the default, so putting on_delete=CASCADE is the same thing as putting nothing.

另外,值得注意的是,如果您正在选择的行为是on_delete=CASCADE,那么它实际上不会添加到任何迁移中。我猜这是因为它是默认的,所以输入on_delete=CASCADE就等于不输入任何东西。

#1


185  

This is the behaviour to adopt when the referenced object is deleted. It is not specific to django, this is an SQL standard.

这是在删除引用对象时要采用的行为。它不是django特有的,这是一个SQL标准。

There are 6 possible actions to take when such event occurs:

当这类事件发生时,有六种可能的行动:

  • CASCADE: When the referenced object is deleted, also delete the objects that have references to it (When you remove a blog post for instance, you might want to delete comments as well). SQL equivalent: CASCADE.
  • CASCADE:当被引用的对象被删除时,也要删除对它有引用的对象(例如,当你删除一个博客文章时,你可能也想要删除评论)。SQL等效:级联。
  • PROTECT: Forbid the deletion of the referenced object. To delete it you will have to delete all objects that reference it manually. SQL equivalent: RESTRICT.
  • 保护:禁止删除引用的对象。要删除它,您必须删除所有手动引用它的对象。SQL等效:限制。
  • SET_NULL: Set the reference to NULL (requires the field to be nullable). For instance, when you delete a User, you might want to keep the comments he posted on blog posts, but say it was posted by an anonymous (or deleted) user. SQL equivalent: SET NULL.
  • SET_NULL:将引用设置为NULL(要求字段为空)。例如,当您删除一个用户时,您可能希望保留他在博客文章中发布的评论,但您可能会说它是由一个匿名(或已删除)用户发布的。SQL等效:设置为空。
  • SET_DEFAULT: Set the default value. SQL equivalent: SET DEFAULT.
  • SET_DEFAULT:设置默认值。SQL等效:设置默认。
  • SET(...): Set a given value. This one is not part of the SQL standard and is entirely handled by Django.
  • SET(…):设置给定的值。这个不是SQL标准的一部分,完全由Django处理。
  • DO_NOTHING: Probably a very bad idea since this would create integrity issues in your database (referencing an object that actually doesn't exist). SQL equivalent: NO ACTION.
  • DO_NOTHING:这可能是一个非常糟糕的想法,因为这会在数据库中创建完整性问题(引用一个实际上不存在的对象)。SQL等效:不行动。

Source: Django documentation

来源:Django文档

See also the documentation of PostGreSQL for instance.

例如,请参见PostGreSQL的文档。

In most cases, CASCADE is the expected behaviour, but for every ForeignKey, you should always ask yourself what is the expected behaviour in this situation. PROTECT and SET_NULL are often useful. Setting CASCADE where it should not, can potentially delete all your database in cascade, by simply deleting a single user.

在大多数情况下,级联是预期的行为,但是对于每一个外国人来说,你都应该问问自己在这种情况下预期的行为是什么。PROTECT和SET_NULL通常很有用。在不应该设置的地方设置CASCADE,可以通过简单地删除一个用户来潜在地以CASCADE的方式删除所有的数据库。

#2


23  

The on_delete method is used to tell Django what to do with model instances that depend on the model instance you delete. (e.g. a ForeignKey relationship). The on_delete=models.CASCADE tells Django to cascade the deleting effect i.e. continue deleting the dependent models as well.

on_delete方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例。(如ForeignKey关系)。on_delete =模型。CASCADE告诉Django对删除效果进行级联,也就是继续删除相关的模型。

Here's a more concrete example. Assume you have an Author model that is a ForeignKey in a Book model. Now, if you delete an instance of the Author model, Django would not know what to do with instances of the Book model that depend on that instance of Author model. The on_delete method tells Django what to do in that case. Setting on_delete=models.CASCADE will instruct Django to cascade the deleting effect i.e. delete all the Book model instances that depend on the Author model instance you deleted.

这里有一个更具体的例子。假设您有一个作者模型,它是图书模型中的一个外国人。现在,如果删除Author模型的一个实例,Django不知道如何处理依赖于Author模型实例的Book模型实例。on_delete方法告诉Django在这种情况下该做什么。设置on_delete =模型。CASCADE会指示Django对删除效果进行级联,即删除所有依赖于您删除的Author模型实例的Book模型实例。

Note: on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.

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

Here's the entire official documentation.

这是整个官方文件。

#3


10  

FYI, the on_delete parameter in models is backwards from what it sounds like. You put "on_delete" on a Foreign Key (FK) on a model to tell django what to do if the FK entry that you are pointing to on your record is deleted. The options our shop have used the most are PROTECT, CASCADE, and SET_NULL. Here are the basic rules I have figured out:

FYI,模型中的on_delete参数是向后的,听起来就像这样。将“on_delete”放在模型的外键(FK)上,以告知django,如果记录中指向的FK条目被删除,该如何做。我们商店使用最多的选项是PROTECT、CASCADE和SET_NULL。以下是我总结出的基本原则:

  1. Use PROTECT when your FK is pointing to a look-up table that really shouldn't be changing and that certainly should not cause your table to change. If anyone tries to delete an entry on that look-up table, PROTECT prevents them from deleting it if it is tied to any records. It also prevents django from deleting your record just because it deleted an entry on a look-up table. This last part is critical. If someone were to delete the gender "Female" from my Gender table, I CERTAINLY would NOT want that to instantly delete any and all people I had in my Person table who had that gender.
  2. 当您的FK指向一个查找表时,请使用PROTECT,它确实不应该发生更改,也不应该导致您的表发生更改。如果有人试图删除查找表上的一个条目,PROTECT会阻止他们删除与任何记录绑定的条目。它还防止django仅仅因为删除了查找表上的一个条目而删除您的记录。最后这一部分至关重要。如果有人要从我的性别表中删除性别“女性”,我当然不希望它立即删除我的Person表中所有具有该性别的人。
  3. Use CASCADE when your FK is pointing to a "parent" record. So, if a Person can have many PersonEthnicity entries (he/she can be American Indian, Black, and White), and that Person is deleted, I really would want any "child" PersonEthnicity entries to be deleted. They are irrelevant without the Person.
  4. 当您的FK指向“父”记录时,请使用CASCADE。因此,如果一个人可以有许多个人种族条目(他/她可以是美国印第安人、黑人和白人),而这个人被删除,我真的希望删除任何“儿童”个人种族条目。没有人,他们是无关紧要的。
  5. Use SET_NULL when you do want people to be allowed to delete an entry on a look-up table, but you still want to preserve your record. For example, if a Person can have a HighSchool, but it doesn't really matter to me if that high-school goes away on my look-up table, I would say "on_delete=SET_NULL." This would leave my Person record out there; it just would just set the high-school FK on my Person to null. Obviously, you will have to allow null=True on that FK.
  6. 当您确实希望允许人们删除查找表上的一个条目时,请使用SET_NULL,但仍然希望保留记录。例如,如果一个人可以上高中,但是如果那个高中在我的查找表上消失了,我就会说“on_delete=SET_NULL”。这会留下我的个人记录;它只会把我的人的高中FK设为空。显然,在FK上必须允许null=True。

Here is an example of a model that does all three things:

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

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'

As a last tidbit, did you know that if you don't specify on_delete (or didn't), the default behavior is CASCADE? This means that if someone deleted a gender entry on your Gender table, any Person records with that gender were also deleted!

最后,您是否知道如果不指定on_delete(或不指定),默认行为是CASCADE?这意味着如果有人删除了您的性别表上的性别条目,任何具有该性别的人记录也被删除!

I would say, "If in doubt, set on_delete=models.PROTECT." Then go test your application. You will quickly figure out which FKs should be labeled the other values without endangering any of your data.

我会说,“如果有疑问,请设置on_delete=models.PROTECT。”然后去测试你的应用程序。您将很快发现哪些FKs应该被标记为其他值,而不会危及您的任何数据。

Also, it is worth noting that on_delete=CASCADE is actually not added to any of your migrations, if that is the behavior you are selecting. I guess this is because it is the default, so putting on_delete=CASCADE is the same thing as putting nothing.

另外,值得注意的是,如果您正在选择的行为是on_delete=CASCADE,那么它实际上不会添加到任何迁移中。我猜这是因为它是默认的,所以输入on_delete=CASCADE就等于不输入任何东西。