我可以控制Django中级联删除的顺序吗



我有这样的模型:

class Parent(models.Model):
pass
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
class Log(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
detail = models.TextField()

我还有一个这样的信号:

@receiver(post_delete, sender=Child)
def handle_delete_child(sender, instance, **kwargs):
log = Log(parent = instance.parent, detail="child deleted")
log.save()

现在,如果我试图删除父级,我可以通过调试看到步骤如下:

  1. 删除父级的日志
  2. 删除父级的子级(导致根据信号写入新日志(
  3. 尝试删除父项,但以"失败;无法删除或更新父行:外键约束失败";,我认为是在步骤2中创建的日志上

如果我能够指定#2应该在#1之前发生,我认为这会解决问题,但我在文档中找不到任何关于这些事情的参考。即使是像新信号或模型方法覆盖这样的创造性解决方案也会受到欢迎。

多亏了@Anentropic的评论和这个问题django暂时禁用了信号,我才想出了这个解决方案。我不需要更改问题中的任何现有代码。

@receiver(signals.pre_delete, sender=Parent)
def handle_delete_project(sender, instance, **kwargs):
signals.post_delete.disconnect(handle_delete_child, sender=Child)

@receiver(signals.post_delete, sender=Parent)
def handle_delete_project(sender, instance, **kwargs):
signals.post_delete.connect(handle_delete_child, sender=Child)

在此之前,我曾尝试在Parent.delete方法中执行此操作,但如果在Django管理中进行批量删除,则不会调用该方法。

最新更新