出库时的 stock.move.line 是如何确定的
用通俗但不失源码细节的方式,讲清楚 Odoo 出库时 stock.move.line 的生成逻辑:从 stock.move、stock.quant、移除策略到 lot/serial 拆行。
CATEGORY FOCUS
聚合 Odoo 开发基础、源码理解、ORM、模型、视图、安全与扩展实践。
TOPIC PICKS
用通俗但不失源码细节的方式,讲清楚 Odoo 出库时 stock.move.line 的生成逻辑:从 stock.move、stock.quant、移除策略到 lot/serial 拆行。
很多人以为 read_group 的日期分组只是 SQL 里的 date_trunc。可从 Odoo ORM 源码看,真正展示给用户的分组标签、用于 drill-down 的 __domain、以及 datetime 的时区换算,都是在 read_group 格式化阶段重新拼出来的。
很多人把 safe_eval 理解成“绝对安全的 Python 执行器”,但 Odoo 19 更准确的做法是受限求值:它限制可用 builtins、校验字节码、控制求值上下文,再把 server action 的 env、model、record、records、log 等对象显式喂进去。它很有用,但绝不是万能隔离层。
很多人以为 Odoo 看板上的空列只是前端自己补出来的占位 UI,但 Odoo 19 实际把这件事做进了字段定义与 read_group 结果整形层:字段声明 group_expand 后,系统会主动把“当前没有记录的组”补进结果里。
很多人以为给 recordset 套上 sudo() 或 with_user(admin) 之后,one2many / many2many 的 Command 就一定能通过。Odoo 19 实际专门给 x2many 命令加了一层防线:当目标模型声明 _allow_sudo_commands=False 时,框架会主动撤销这类提权写法,重新按事务原始用户做权限检查。
很多开发者把 Odoo 权限理解成“两层门”:先看 ACL,再看 record rule。但从 ir_rule.py 的 _compute_domain 和 models.py 的 _check_access 看,系统实际做的是“先判模型权限,再把全局规则、组规则、继承模型规则合成一个 domain,最后对真实记录集做过滤和报错”。
很多人看到 sale.order.line 里的 display_type,会下意识把它理解成报价单上的 section 和 note 排版辅助。可一旦把它和 is_downpayment、qty_to_invoice、invoice_status 放在一起看,就会发现它其实定义了“哪些行参与业务计算、哪些行只负责结构呈现”的硬边界。本文结合 sale_order_line.py 把这条边界讲透。