Odoo 的 _inherits 不是代码继承,而是代理建模:delegation 真正解决什么问题
很多人把 _inherits 当成“高级版 _inherit”,结果越做越乱。其实它更接近“当前模型通过一个 Many2one 代理父模型字段”,本质是组合建模,不是 Python 继承。
ARTICLE LIBRARY
持续记录源码理解、业务流程、模块开发经验与踩坑总结。
很多人把 _inherits 当成“高级版 _inherit”,结果越做越乱。其实它更接近“当前模型通过一个 Many2one 代理父模型字段”,本质是组合建模,不是 Python 继承。
现在的 Odoo 里,company_dependent 字段已经不是很多人印象中的 ir.property 老路子了。它更像“字段本体存 JSONB,多公司值按公司 id 取,缺值时再走 ir.default 回退”。
很多人以为 project_stock 会自动帮项目生成领料单或把库存流程深度嵌进任务里,但官方源码做得其实很克制:它先在 stock.picking 上补一个 project_id,再给项目页挂上指向收货、发货和全部调拨的嵌入动作,并通过 restricted_picking_type_code、default_project_id 和 default_partner_id 把打开后的列表与新建行为限制在项目语义里。
很多人以为发票二维码只是报表上塞一张图片,但从 account_move.py、res_partner_bank.py 和 account_qr_code_emv 的实现看,Odoo 真正做的是先挑可用的 QR 方法,再校验银行账户是否满足国家规则,最后把金额、币种、商户信息和引用组装成 EMV 字符串并交给条码引擎渲染。
很多人看到 website_cf_turnstile 只有几段前端脚本和一个 ir.http 扩展,就以为它只是给表单塞了个 Cloudflare 小组件。其实它真正关键的地方,是把 site key 注入前端、把提交按钮先锁住、再在控制器统一走 _verify_request_recaptcha_token 校验,并把各种失败状态翻译成可控异常。
很多人把 safe_eval 理解成“绝对安全的 Python 执行器”,但 Odoo 19 更准确的做法是受限求值:它限制可用 builtins、校验字节码、控制求值上下文,再把 server action 的 env、model、record、records、log 等对象显式喂进去。它很有用,但绝不是万能隔离层。