Как остановить каскадное удаление, вызывающее циклическую ошибку обновления в Django? - PullRequest
0 голосов
/ 14 июля 2020

У меня есть две модели с отношением FK между ними. Существует также обработчик сигналов post_save и post_delete, который обновляет некоторое производное поле на основе связанных дочерних элементов.

class Parent(models.Model):
    derived_field = models.CharField(...)

class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=CASCADE)


def update_parent(sender, instance, **kwargs):
    instance.parent.derived_field = get_derived_field_value(instance)
    instance.parent.save()


post_save.connect(update_parent, sender=Child)
post_delete.connect(update_parent, sender=Child)

Все это работает нормально, пока вы не удалите родительский экземпляр, который имеет связанные дочерние экземпляры. В этот момент мы сталкиваемся с IntegrityError, поскольку наш обработчик сигнала post_delete пытается сохранить экземпляр, который также удаляется в той же транзакции.

Стоит отметить: производное поле создается для повышения производительности - и на самом деле это поле MultiPoint geo django, которое затем используется в более поздних запросах выбора как внутри, так и за пределами ORM, я не хочу его удалять!

Один из вариантов - не каскадировать удалить, но сделать поле parent обнуляемым, а затем каким-то образом удалить эти экземпляры по отдельности. Есть ли другие варианты?

...