Как узнать, когда цепочки хуков/сигналов жизненного цикла django завершают работу?

У меня есть модель Animal и модель Herd, которые выглядят следующим образом:

from django_lifecycle.hooks import AFTER_CREATE

class Animal(models.Model):
    parent = OneToOneField("self", related_name="child")
    age = IntegerField()

class Herd(models.Model):
    animal = OneToOneField(Animal)
    total_age = IntegerField()
    
    @hook(AFTER_CREATE)
    def create_animal_child(self):
        if self.animal.child.exists():
            Herd.objects.create(parent=self, animal=self.animal.child)

    def save_total_age(self):
        total_age = self.animal.age
        position = self.animal
        while position.child.exists():
            total_age += position.child.age
            position = position.child

Идея заключается в том, что вы создаете свои Animal. Затем вы создаете свой Herd для самого верхнего животного, которое вы хотите. Затем AFTER_CREATE стада создаст "цепочку" из всех Herd объектов для детей Animal, детей детей и так далее.

E.g.

a1 = Animal.objects.create(age=10)
a2 = Animal.objects.create(parent=a1, age=7)
a3 = Animal.objects.create(parent=a2, age=3)

h1 = Herd.objects.create(animal=a1)
# Two Herd objects with an "animal" field pointing to a2 and a3 respectively are automatically created

h1.save_total_age() # h1.total_age = 20 # 10 + 7 + 3

Все в порядке.

Моя проблема заключается в том, что для моего front-end, как я могу определить, когда все соответствующие Animal AFTER_CREATE хуки завершили работу, чтобы я знал, что нужно вызвать мой calculate_total_age метод?

Допустим, у меня есть следующие конечные точки REST API:

example.com/api/animals/<pk>
example.com/api/herds/<pk>
example.com/api/herds/<pk>/save_total_age

Если я выполняю POST в example.com/api/herds/<pk> для создания Herd, я вызываю save_total_age() сразу после создания "родителя" Herd - и не обязательно после создания всех "детей" Herd через хук AFTER_CREATE.

axios.post(
    "example.com/api/herds/",
    {animal_id: 1}
).then((response) => {
    axios.post(
        `example.com/api/herds/${response.data.pk}/save_total_age`,
        {},
    )
});

Как я могу настроить мои backend signals и/или frontend async/await так, чтобы save_total_age() запускался только после завершения моей AFTER_CREATE цепочки?

Сигналы (которые вызываются этими хуками) работают синхронно, а не асинхронно. Поэтому, когда вы вызываете create() для вашего первого услышанного объекта, он всегда будет выполнять хук AFTER_CREATE и создавать 2-й услышанный объект, прежде чем он вернется и позволит вам выполнить метод save_total_age().

Другими словами, это должно прекрасно работать как есть.

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