仅供参考,on_delete
模型中的参数从听起来像是倒过来的。您on_delete
在模型上放置了外键(FK),以告诉django如果删除了记录中指向的FK条目该怎么办。选项我们店已经使用的大多是PROTECT
,CASCADE
和SET_NULL
。这是我弄清楚的基本规则:
- 使用
PROTECT
时,你的FK指向一个查表真的不应该被改变,并且肯定不会引起你的表来改变。如果有人试图删除该查询表上的条目,则PROTECT
防止该条目与任何记录绑定时删除该条目。它还可以防止从删除的Django 你的记录,只是因为它删除了一个查找表中的条目。最后一部分至关重要。 如果有人要从“性别”表中删除性别“女性”,我肯定不希望立即删除我在“人”表中拥有该性别的任何人。
- 使用
CASCADE
时,你的FK指向“父”的纪录。所以,如果一个人可以有很多PersonEthnicity项(他/她可以是美洲印第安人,黑色和白色),而那个人被删除了,我真的会想什么“孩子” PersonEthnicity条目被删除。没有人,他们是无关紧要的。
- 使用
SET_NULL
时,你也希望人们被允许删除查找表中的条目,但你仍然要保留记录。例如,如果某人可以拥有一所高中,但对我而言,那所高中不在我的查询表上并不重要on_delete=SET_NULL
。这会将我的“个人”记录保留在那里;只会将“我的人”上的高中FK设置为null。显然,您必须允许null=True
该FK。
这是一个可以完成所有三件事的模型示例:
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
和放置任何东西都是一样的。