为什么Django会对外键进行级联删除?

时间:2015-09-26 04:14:50

标签: python sql django database

Django在具有外键的模型上进行级联删除作为默认值。也就是说,你在A中有一个指向B的ForeignKey,你删除了B,那么A也会被删除。

This is known and documented,但我没有找到任何关于将其设为默认设计决策的合理理由,因为它看起来有多么不直观。有谁知道为什么会这样?

2 个答案:

答案 0 :(得分:11)

7年前......

故障单已开启#7539

开始讨论的地方。

  

年前由benjaoming

     

有人请求讨论......我刚遇到过这个,   而我所缺乏的是知道正在发生的事情   级联删除,因为它非常危险(你丢失数据!!)   并偷走了很多时间。但是,预防它很简单。重写   模型的delete()方法和相关的调用clear()   model的外键很简单,而且是手动实现的   所有程序员都应该能够理解。但我能想到   另一种选择:如果有问题的外键,如果null = True,为什么   删除相关实例时不自动使用SET NULL?   对我来说,这比CASCADE更“直观”。毕竟,   null = True是程序员指定并且必须处理的事情   随着实施的任何地方,这也是他不需要的原因   级联删除这种关系。此外,如果可以使用on_delete   要设置在关键字段中,它必须符合null选项。   并与创造1:1的“直觉论证”一起   两种选择之间的对应关系。然后是“逻辑论证”:   Django在Python代码中处理它的逻辑,而不是在数据库中处理它   保持为一个简单的存储引擎。 RESTRICT选项是验证   问题,并且在大多数情况下可能会以这种方式处理,所以有   执行它的数据库将是多余的。启用它   模型级可以为一些不错的新自动验证铺平道路   在ModelForms中,所以我觉得这听起来很不错。如果这一切   实现后,我建议从key中删除null选项   字段并根据on_delete进行设置。

多年以后,该小组再次讨论了此事。

Django开发人员(对Django本身的贡献)
changing the on_delete=CASCADE default

然后创建了其他故障单 #21127#21961

我们到了这里。 ForeignKey and OneToOneField on_delete argument

  

为了提高对级联模型删除的认识,   将需要ForeignKey和OneToOneField的on_delete参数   Django 2.0。

     

更新模型和现有迁移以显式设置参数。   由于默认值为models.CASCADE,因此请将on_delete = models.CASCADE添加到   所有不使用其他选项的ForeignKey和OneToOneFields。   如果不这样做,您也可以将其作为第二个位置参数传递   关心与旧版Django的兼容性。

答案 1 :(得分:6)

对此in this ticket进行了相当冗长的讨论。在Django 2.0中#myDiv { transition: background-color 2s; } 参数will be required,因此当前的默认行为将不再适用。