Odoo 存储计算字段在手写 SQL 后为什么必须显式 modified()
手写 SQL 只改了数据库,不会自动走 Odoo 的缓存失效和依赖传播。要让存储计算字段恢复一致,关键是理解 invalidate_recordset()、modified() 与 flush_recordset() 的分工。
ARTICLE LIBRARY
持续记录源码理解、业务流程、模块开发经验与踩坑总结。
手写 SQL 只改了数据库,不会自动走 Odoo 的缓存失效和依赖传播。要让存储计算字段恢复一致,关键是理解 invalidate_recordset()、modified() 与 flush_recordset() 的分工。
很多人以为 read_group 的日期分组只是 SQL 里的 date_trunc。可从 Odoo ORM 源码看,真正展示给用户的分组标签、用于 drill-down 的 __domain、以及 datetime 的时区换算,都是在 read_group 格式化阶段重新拼出来的。
很多人以为 Register Payment 只是把选中的发票一起做成付款。可从 account_payment_register 源码看,Odoo 其实会先按合作伙伴、应收应付科目、币种、收付款方向和对方银行账户切 batch,再决定是一笔 payment 还是多笔。
很多人把按钮显示问题都归因于 view 继承或权限错配。可从 ir_ui_view 与 web 客户端源码看,Odoo 对按钮的处理至少分三层:服务端先按 groups 裁剪节点,再把 invisible/readonly 条件带到前端求值,最后还会受 create/edit/delete 这类 activeActions 影响。
在 Odoo 里,核销不是“要么没核销,要么已核销”这么简单。系统会先创建 `account.partial.reconcile` 这条连接边,再在整组分录都真正归零后,补出 `account.full.reconcile` 作为整图收口。
你明明没写 `('active', '=', True)`,搜索结果却默认把归档记录排除了;你明明知道有那条数据,下拉框却像没看见它。很多这类问题,根子都在 active_test 这层隐式过滤上。