重算链路

Odoo 计算字段为什么有时改了没跟着变:depends 声明与重算链路讲透

很多 compute 字段问题,看起来像缓存怪异,实际上常常是 depends 没声明全。本文把“哪些变化会触发重算”这条链讲清楚。

Odoo 开发
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

很多 Odoo 计算字段“改了却没更新”的问题,表面像缓存怪异,实际常见根因是:

系统并不知道哪些字段变化应该触发这条 compute 结果重算。

而这件事最核心的入口,往往就是 @api.depends()

所以 depends 不是装饰语法,而是在告诉 ORM:

  • 这条结果依赖谁
  • 谁变了就该重新算

为什么这类问题总让人觉得像玄学

因为用户看到的是:

  • A 字段都改了
  • 为什么 B 这个计算结果没跟上?

如果不理解重算链,你就很容易觉得:

  • 系统缓存坏了
  • ORM 不稳定
  • 需要多刷新几次

但更常见的现实是:

  • 你脑子里知道 B 依赖 A
  • 可 ORM 并没有被明确告知这层依赖

所以它不会自动替你猜。


depends 真正在声明什么

它最本质是在说:

当这些字段变化时,这个计算结果应该被视为过期并重新计算。

这点特别关键。

因为 compute 本身只说明“怎么算”, 而 depends 说明的是“什么时候必须重算”。

一个是计算公式,一个是失效条件。


为什么“计算逻辑写对了”还不够

因为系统不仅要知道公式,还要知道触发时机。

如果 depends 没写全,常见结果就是:

  • 某些场景下能更新
  • 某些场景下又像没反应

这时你会误以为 ORM 很随机。

其实很多时候不是随机,而是:

  • 某条变化路径根本没进入重算触发链。

为什么跨字段、跨关系依赖更容易漏

因为你脑中想的是业务语义:

  • 这个结果当然也受那个对象影响

但系统需要的是:

  • 具体哪条字段路径会触发失效

这就是为什么一旦关系链变深,depends 更容易漏写。

不是因为逻辑变神秘,而是因为触发路径变长了。


为什么很多“缓存问题”其实不是缓存问题

有些现象看起来像缓存没刷新:

  • 重新进页面又好了
  • 某些入口改了会更新,另一些不会

这很容易让人怪缓存。

但如果 depends 声明不完整,就会出现这种“像缓存,其实是失效条件没声明全”的假象。

所以排查时,最好先问:

  • 这条 compute 的依赖路径有没有完整告诉 ORM?

实战里最容易踩的 5 个坑

1. 只写 compute,不认真写 depends

重算触发会不稳。

2. 以为系统会自动理解所有业务依赖

ORM 不会替你猜全。

3. 关系链依赖漏写

这是高频问题。

4. 把失效条件问题误判成缓存问题

排查方向会跑偏。

5. 看到某些场景能更新,就以为整体没问题

其实可能只是命中了部分路径。


一句话记忆法

把它记成一句话:

compute 说明“怎么算”,depends 说明“谁变了必须重算”;很多看起来像缓存异常的问题,本质上其实是重算依赖没声明完整。

理解这一句,计算字段问题会清楚很多。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。