Odoo 的 property 字段为什么不在业务表里:ir.property 存储、公司回退与搜索翻译链
`company_dependent=True` 看起来像给字段加了个多公司开关,但它背后不是普通列值覆盖,而是由 ir.property、默认回退和上下文公司共同决定读写结果。理解这条链,才能解释为什么同一字段在不同公司下会变、为什么搜索也不像普通字段那样直译成简单 SQL。
ARTICLE LIBRARY
持续记录源码理解、业务流程、模块开发经验与踩坑总结。
`company_dependent=True` 看起来像给字段加了个多公司开关,但它背后不是普通列值覆盖,而是由 ir.property、默认回退和上下文公司共同决定读写结果。理解这条链,才能解释为什么同一字段在不同公司下会变、为什么搜索也不像普通字段那样直译成简单 SQL。
很多团队觉得 Odoo 的补货日期像在“随缘”,今天建议下单,明天又提前几天。真去看 stock_rule、stock_orderpoint 和相关日期字段后会发现,系统并不是乱算,而是在把需求日期沿着规则提前期、供应商提前期和 visibility days 一层层倒排。
很多开发者知道 @api.depends,却低估了 @api.depends_context 的分量。它不是给代码加点语义说明,而是直接决定字段缓存怎样按上下文分桶、何时必须重算,以及为什么同一条记录会在不同语言、公司或用户下读出不同结果。
很多人第一次看 Pull Rule,会觉得系统像“倒着长单据”:明明只是下游库位缺货,怎么上一段调拨、采购或制造动作就自己冒出来了?从 stock_rule.py 看,Pull Rule 的关键不是“货往哪走”,而是“哪里产生需求、系统就去哪里找能把货拉过来的规则”。
很多人以为 Chatter 里的字段变更只是生成一句“X 改成 Y”。但从 mail.tracking.value 与 account 对 mail.message 的扩展看,Odoo 真正在维护的是一份结构化差异数据:既要按字段类型存储旧值/新值,又要在展示时再判断当前用户有没有权限看到这些字段。
很多人把 Odoo 编号理解成“找到最后一条,再加一”。但从 sequence_mixin.py 看,真正困难的不是 +1,而是先判断这串编号按月重置、按年重置还是永不重置,再在并发事务里安全地抢到下一个号,还不能把日期和编号链打乱。