先说结论
很多 Odoo 字段设计之所以后面难维护,不是因为不会写字段,而是因为一开始没想清楚这个字段属于哪一类。
一个字段常见的几种身份其实很不一样:
- 普通字段:直接存值
- related 字段:从别的字段路径取值
- compute 字段:根据逻辑算出来
- inverse:允许用户反向写回
- store:决定计算结果要不要落库
这些概念如果混在一起不分层,模型就会越来越乱。
为什么 related 和 compute 很容易被混用
因为它们看起来都像“这个值不是手工直接填的”。
但本质区别非常大:
- related 更像“沿着关系链把现成值拿过来”
- compute 更像“按规则重新计算出一个值”
如果只是简单取别处已有值,related 往往更自然; 如果需要业务逻辑、判断分支、聚合计算,那通常更像 compute。
related 最适合什么场景
related 最适合:
- 这个值本来就已经存在于别处
- 这里只是想方便展示或搜索
- 关系路径明确而稳定
你可以把它理解成:
我不是重新发明一个值,我只是把另一处值映射过来。
所以它特别适合做“从关联对象引一列过来”的场景。
compute 最适合什么场景
compute 最适合:
- 这个值需要基于多字段综合计算
- 逻辑里有条件分支
- 值不只是简单沿关系读取
- 需要表达明确的业务推导过程
也就是说,compute 真正适合的是“有推导逻辑”的字段,而不是一切“不是手填”的字段。
store=True 到底在决定什么
很多人把 store 理解成“高级一点”或“性能更好一点”,这都不够准确。
它真正决定的是:
这个计算结果要不要作为持久化结果存下来。
这会直接影响:
- 搜索是否方便
- 排序是否方便
- 重算机制
- 一致性维护成本
所以 store 不是随手一勾,而是设计选择。
为什么 inverse 很容易被误用
inverse 常让人误解成“给 compute 字段补个写入方法”。
这句话不算错,但还不够。
更准确地说,它表达的是:
如果用户改了这个计算字段,系统应该怎样把这个意图反向落到真实来源上。
所以 inverse 不是装饰,它意味着你真的允许这个字段成为交互入口。
如果你根本不希望用户改它,很多时候就不该上 inverse。
一个特别实用的判断方法
设计字段时,可以先问自己:
1. 这个值是不是本来就在别的字段里已经存在
如果是,先想 related。
2. 这个值是不是要通过业务规则推导
如果是,先想 compute。
3. 这个结果要不要落库,支持搜索排序统计
如果要,再考虑 store=True。
4. 用户改这个字段时,我是否真的希望系统反推回源头
如果是,才考虑 inverse。
实战里最容易踩的 5 个坑
1. 明明只是 related,却写成复杂 compute
把简单问题做重了。
2. 明明是复杂推导,却硬写 related
结果表达不了真实业务逻辑。
3. store=True 开得很随意
后面重算和一致性成本上来。
4. 给不该编辑的字段补 inverse
把原本稳定的读模型变成易错写入口。
5. 一开始没想清楚“真源头”在哪
最后模型字段像复制粘贴出来的一层雾。
一句话记忆法
把这套关系记成一句话:
related 是映射现成值,compute 是推导新值,store 决定是否落库,inverse 决定用户改动时如何反写回真实来源。
理解这一句,Odoo 字段设计会清楚很多。
DISCUSSION
评论区