Могу ли я контролировать порядок каскадных удалений в 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. Попытайтесь удалить родителя, но происходит сбой с сообщением "Cannot delete or update a parent row: a foreign key constraint fails", я думаю, на логе, созданном в шаге 2.

Если бы я мог указать, что #2 должен произойти до #1, я думаю, это решило бы проблему, но я не могу найти никаких ссылок на такие вещи в документации. Даже креативное решение вроде нового сигнала или переопределения метода модели будет приветствоваться.

Благодаря комментарию @Pouya и этому вопросу django temporarily disable signals я смог прийти к этому решению. Мне не пришлось изменять никакой существующий код из моего вопроса.

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


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

До этого я пробовал делать это в методе Parent.delete, но он не вызывается, если вы удаляете массово в админке Django.

Вернуться на верх