【问题标题】:How to know when chained django lifecycle hooks/signals are finished running?如何知道链式 django 生命周期钩子/信号何时完成运行?
【发布时间】:2021-09-21 01:58:28
【问题描述】:

我有一个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

您的想法是创建您的Animals。然后你为你想要的最上面的动物创建你的Herd。然后 Herd 的 AFTER_CREATE 将为 Animal 的孩子、孩子的孩子等创建一个包含所有 Herd 对象的“链”。

例如

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

没关系。

我的问题在于我的前端,我如何知道所有相关的 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

如果我向example.com/api/herds/&lt;pk&gt; 发帖以创建Herd,我会在创建“父”Herd 后立即调用save_total_age() - 不一定在所有“子”Herds 之后已通过 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`,
        {},
    )
});

如何设置我的后端信号和/或前端异步/等待,以便 save_total_age() 仅在我的 AFTER_CREATE 链完成后运行

编辑:我现在最好的解决方案是向save_word_count() 添加一些条件,以确保Herd 链与Animal 链具有相同的对象数。如果是这样,请运行该方法。如果不是,则返回错误请求并重试 POST。

【问题讨论】:

    标签: django django-rest-framework async-await django-signals


    【解决方案1】:

    信号(由这些钩子调用)同步运行,而不是异步运行。所以当你第一次调用create() 时,它总是会运行AFTER_CREATE 钩子并创建第二个Heard 对象,然后它会返回并让你运行save_total_age() 方法。

    换句话说,这应该可以正常工作。

    【讨论】:

    • 澄清一下,信号“链”也是如此吗?那么在返回 Herd 1 的 2XX 代码之前,创建 Herd 1 也会一直创建 Herd 2、3 等?我已尝试搜索此内容,但找不到任何内容...您能指出我的任何文档吗?
    • 是的。信号链就像任何普通的函数链一样被调用。这些调用在当前请求中是同步的。另请参阅此答案:stackoverflow.com/questions/19731349/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 2020-01-15
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多