Django:ForeignKey on_delete SET_DEFAULT行为

时间:2018-01-18 13:28:50

标签: django

请允许我考虑以下两种模式:

class Policy(models.Model):
        name = models.SlugField(max_length=256, blank = False, unique = True)
def default_policy():
        return Policy.objects.get(name='default').pk
class Item(models.Model):
        policy = models.ForeignKey('Policy', on_delete=models.SET_DEFAULT, default=default_policy)

除了一个操作外,一切都按预期工作。没有任何例外,我仍然可以做以下事情:

p = Policy.objects.get(name='default')
p.delete()

这会产生孤立的Item s,它们指的是“默认”Policy对象。 遗憾的是,此操作会导致数据库中出现完整性问题,因为Item个policy_id列现在引用了Policy表的错过记录。

我怎么能防止这种情况发生?如果没有Policy引用它,则删除“默认”Item是我可以接受的。

1 个答案:

答案 0 :(得分:2)

这取决于您的业务需求。每个Item是否应始终指向有效的Policy?当Policy被删除时,从业务角度来看,需求是什么?指向它的Item是否也应删除?我们不了解您的要求,因此很难回答您的问题。从技术角度来看,这些是您的选择:

  • 如果您希望在删除on_delete=CASCADE时删除Item,请设置Policy
  • 设置on_delete=PROTECT如果您还不想删除任何Policy,如果仍然有Item指向该try: policy.delete(); except ProtectedError: ...。在这种情况下,您必须在代码中on_delete=SET_DEFAULT来处理这种情况。
  • 如果您知道不会删除默认政策,请设置delete(您可以覆盖Policy上的on_delete=SET_NULL方法以避免删除默认政策。
  • 如果Item没有Policy,请设置null=True。这可能在某些业务场景中有效。但在这种情况下,您还必须拥有{{1}}。