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

mal*_*vai 10 python sql database django

Django在具有外键的模型上进行级联删除作为默认值.也就是说,假设您在A中有一个指向B的ForeignKey,并且您删除了B,那么A也将被删除.

这是众所周知的,但是我没有找到任何关于将其作为默认设计决策的合理理由,因为它看起来有多么不直观.有谁知道为什么会这样?

Pau*_*soa 11

7年前......

门票开放#7539

它开始被讨论的地方.

几年前由benjaoming

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

多年以后,该小组再次讨论了这个问题.

Django开发人员(对Django本身的贡献)
更改on_delete = CASCADE默认值

然后其他的票被创造 #21127#21961.

我们到了这里. ForeignKey和OneToOneField on_delete参数

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

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

  • 感谢所有这些背景!很高兴听到有计划前进的替代方案,很高兴听到我并不孤单,认为这很傻;-).我特别喜欢明确设置on_null参数的想法.关于它的原始理由的任何想法,还是已经失去了风? (2认同)

sol*_*oke 6

这张票中有一个相当冗长的讨论.在Django 2.0中,on_delete参数将是必需的,因此当前的默认行为将不再适用.