将models_py添加到on_delete会有什么影响,以及我应该在其中添加什么内容?

时间:2017-12-20 21:05:03

标签: python mysql django foreign-keys cascading-deletes

这个答案的内容在“重复的问题”中提供,尽管这比在那里提供的任何答案都要详细得多。

仅供参考,模型中的on_delete参数是从它听起来的后退。您将“on_delete”放在模型上的外键(FK)上,告诉django如果删除了您在记录中指向的FK条目该怎么做。我们商店最常用的选项是PROTECT,CASCADE和SET_NULL。以下是我发现的基本规则:

  1. 当您的FK指向一个确实不应该更改的查找表时,请使用PROTECT,并且当然不应该导致您的表更改。如果有人试图删除该查找表上的条目,PROTECT会阻止它们删除它,如果它绑定到任何记录。它还会阻止django删除您的记录,因为它删除了查找表中的条目。最后一部分是至关重要的。 如果有人要从我的性别表中删除性别“女性”,我绝对不会希望立即删除我个人表中具有该性别的所有人。
  2. 当您的FK指向“父”记录时,请使用CASCADE。因此,如果一个人可以拥有许多PersonEthnicity条目(他/她可以是美洲印第安人,黑人和白人),并且该人删除,我真的想要任何“child”PersonEthnicity条目被删除。没有这个人,他们就无关紧要了。
  3. 执行时,请使用SET_NULL希望允许其他人删除查找表中的条目,但您仍希望保留您的记录。例如,如果一个人可以拥有一个HighSchool,但是如果我的查找表中的那个高中学校消失对我来说并不重要,我会说“on_delete = SET_NULL”。这会留下我的人员记录;它只是将我的Person上的高中FK设置为​​null。显然,你必须在FK上允许null = True。
  4. 这是一个完成所有三件事的模型示例:

    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'
    

    作为最后的消息,您是否知道如果您指定on_delete(或没有),则默认行为是CASCADE?这意味着,如果有人在您的性别表中删除了性别条目,那么任何具有该性别的人员记录也会被删除!

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

    另外,值得注意的是on_delete = CASCADE实际上没有添加到任何迁移中,如果这是您选择的行为。我想这是因为它是默认值,所以把on_delete = CASCADE与什么都不做是一回事。

0 个答案:

没有答案