先说结论
在 Odoo 里,并不是所有字段值都只取决于数据库里那一列。
有些值天然会受这些因素影响:
- 当前公司
- 当前语言
- 当前 pricelist
- 当前用户上下文
所以你看到“同一条记录,在不同场景下值不一样”,不一定是 bug,而可能是系统设计本来就允许它依赖上下文。
这时最关键的两个概念就是:
@api.depends_contextcompany_dependent
为什么这个主题很容易让人误判
因为很多开发者脑子里默认是:
一条记录的一个字段,就应该只有一个固定值。
但 Odoo 有不少业务场景并不是这样。
比如:
- 同一个产品在不同公司下有不同属性
- 同一个价格在不同 pricelist 下解释不同
- 同一个显示结果会受语言或上下文开关影响
如果你还用“固定字段值”的思路去看,就会误以为系统不稳定。
其实系统是在支持“值受上下文影响”这件事。
@api.depends_context 解决的是什么问题
普通 @api.depends() 关注的是:
- 哪些字段变化会影响 compute 结果
而 @api.depends_context() 关注的是:
- 哪些上下文变化也会影响 compute 结果
这特别适合那些“不是底层字段变了,但计算口径变了”的场景。
比如:
- 当前公司切换了
- 当前 pricelist 变了
- 当前显示语言或某个上下文标志变了
这类时候,字段本身没变,但结果应该重算。
为什么这不是“可有可无的小装饰”
因为如果一个 compute 实际依赖上下文,你却没把它声明出来,后果通常是:
- 某些场景值看起来是旧的
- 缓存行为不符合预期
- 不同入口显示不一致
- 你以为系统随机,其实是依赖没声明完整
所以 depends_context 的价值不在语法,而在:
告诉 ORM:这个结果不只受字段影响,也受上下文影响。
company_dependent 又是什么
company_dependent=True 更适合理解成:
同一个字段,在不同公司维度下可以有不同持久值。
这不是简单“根据当前公司算一个显示结果”,而是更接近:
- 你真的允许每个公司各自维护不同值
- 系统会按公司上下文读取对应值
所以它处理的是“多公司持久差异”,不是单纯前端显示差异。
depends_context 和 company_dependent 最大区别
可以这样粗暴但有效地记:
depends_context:结果受上下文影响,需要按上下文重算company_dependent:字段本身在不同公司下就允许存不同值
一个更偏计算依赖声明,一个更偏多公司值存储策略。
这俩混了,设计就很容易走偏。
为什么多公司开发里特别容易踩坑
因为你在一个公司里测通,不代表另一个公司也通。
常见问题包括:
- 在 A 公司看起来正确,切到 B 公司值不对
- 以为字段是全局的,结果其实公司隔离
- 以为只是显示问题,结果底层存储就分公司
- compute 结果其实受公司上下文影响,却没声明
depends_context('company')
所以多公司开发里,一个特别重要的习惯是:
先想清楚这个差异到底是“显示/计算口径差异”,还是“字段值本身就分公司存储”。
一个特别实用的判断方法
如果你面对“同一字段在不同公司下不一样”这种需求,可以先问:
1. 这是同一套底层值,只是展示/计算口径会变吗?
如果是,优先想 depends_context。
2. 这是每个公司真的要各自维护不同值吗?
如果是,更接近 company_dependent。
3. 这两层是不是同时存在?
有些复杂场景既有公司分值,又有上下文计算差异,这就要把设计拆清楚。
实战里最容易踩的坑
1. compute 明明依赖公司上下文,却没声明 depends_context
结果缓存不稳。
2. 其实要分公司存值,却硬写成普通字段 + compute
后期维护会很痛。
3. 其实只是显示差异,却误上 company_dependent
把简单问题做复杂了。
4. 只在一个公司下测试
这是多公司 bug 的温床。
一句话记忆法
把它记成一句话:
depends_context说明“这个结果会随上下文变”,company_dependent说明“这个字段在不同公司下本来就能有不同值”。
理解这句,多公司与上下文字段问题会清楚很多。
DISCUSSION
评论区