You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断Django链式lifecycle hooks/signals全部执行完成?

解决方案

最优方案:后端自动执行计算,无需前端二次请求

默认情况下django-lifecycle的AFTER_CREATE钩子为同步阻塞执行,你创建顶层Herd时触发的链式创建操作会全部在当前请求的事务内完成,完全可以在链式创建结束后自动触发总年龄计算,前端不需要额外调用接口。

代码修改步骤:

  1. 先补全Herd模型缺失的parent字段(你现有代码中创建Herd时传了parent参数但模型未定义):
class Herd(models.Model):
    animal = OneToOneField(Animal, on_delete=models.CASCADE)
    # 补充parent外键字段
    parent = models.ForeignKey("self", null=True, blank=True, related_name="children", on_delete=models.CASCADE)
    total_age = IntegerField(null=True, blank=True)
    
    @hook(AFTER_CREATE)
    def create_animal_child(self):
        if self.animal.child.exists():
            Herd.objects.create(parent=self, animal=self.animal.child)
        # 判断当前为顶层Herd(对应的Animal没有父节点),此时所有子Herd已全部创建完成
        if self.animal.parent_id is None:
            self.save_total_age()
            # 保存计算结果到数据库
            self.save(update_fields=["total_age"])

    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
        # 补充赋值逻辑,原有代码缺了这行
        self.total_age = total_age
  1. 前端调整逻辑:创建Herd的接口返回时,响应数据中已经包含计算完成的total_age字段,直接使用即可,不需要再调用save_total_age接口。

备选方案:保留前端调用逻辑,加重试机制

如果业务逻辑要求必须由前端触发计算,可以采用你想到的数量校验方案,配合前端重试实现:

后端修改

给save_total_age接口加校验逻辑:

  • 先统计当前Animal链的总节点数
  • 再统计对应已经创建的Herd总数量
  • 二者不相等时返回425 Too Early状态码,提示前端重试

前端修改

把原有回调逻辑改为带重试的async/await逻辑:

const initHerd = async (animalId) => {
  // 创建顶层Herd
  const { data: herd } = await axios.post("example.com/api/herds/", { animal_id: animalId })
  const maxRetry = 5
  let retryTimes = 0
  while (retryTimes < maxRetry) {
    try {
      await axios.post(`example.com/api/herds/${herd.pk}/save_total_age`)
      // 计算成功,跳出循环
      break
    } catch (err) {
      if (err.response?.status === 425) {
        retryTimes++
        // 间隔500ms重试
        await new Promise(resolve => setTimeout(resolve, 500))
      } else {
        // 非超时错误直接抛出
        throw err
      }
    }
  }
  if (retryTimes >= maxRetry) {
    alert("计算超时,请稍后重试")
  }
}

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:15:00