Odoo自定义模型browse首次调用返回错误值问题
问题原因及解决办法
为什么首次访问字段会出错?
这是_auto=False自定义模型的ORM缓存机制导致的:
- 这类模型没有Odoo自动生成的数据库表,数据靠自定义SQL或
_select/_from语句加载,ORM对它的字段缓存初始化逻辑和普通模型不一样。 - 在
_read_format执行初期,ORM实例的字段缓存还没从原始查询结果里正确加载,第一次访问analytic_line_type_id时,会返回缓存里的默认值(或者旧的残留值,就是你调试里看到的id=1记录)。 search_read是直接跑SQL查数据库,绕开了ORM实例的缓存,所以每次都能拿到正确值;而第一次访问字段后,ORM会把正确值存进缓存,后面再访问就正常了。
先检查这几个关键点
- 确认模型的
_select语句里明确包含了analytic_line_type_id字段,这是ORM能正确加载这个字段的基础,要是没写,ORM就会用默认值填充。 - 别给这个字段设
store=True,_auto=False模型的字段默认都是store=False,手动设成True会搞乱缓存逻辑。
具体解决方法
补全
_select语句
把目标字段加到自定义查询里:_select = """ SELECT your_table.id AS id, your_table.analytic_line_type_id AS analytic_line_type_id, -- 其他需要的字段... """ _from = "your_table"用计算字段替代直接映射
绕开缓存,动态计算字段值:analytic_line_type_id = fields.Many2one( 'account.analytic.line.type', compute='_compute_analytic_line_type' ) def _compute_analytic_line_type(self): for rec in self: # 直接查数据库拿正确值 self.env.cr.execute( "SELECT analytic_line_type_id FROM your_table WHERE id = %s", (rec.id,) ) result = self.env.cr.fetchone() rec.analytic_line_type_id = result[0] if result else False重载
_read方法手动控制加载
覆盖ORM默认的缓存逻辑,确保字段值正确:def _read(self, fields): res = super()._read(fields) for rec_id, vals in res.items(): if 'analytic_line_type_id' in fields: self.env.cr.execute( "SELECT analytic_line_type_id FROM your_table WHERE id = %s", (rec_id,) ) val = self.env.cr.fetchone() vals['analytic_line_type_id'] = val[0] if val else False return res
内容的提问来源于stack exchange,提问作者m3asmi
相关产品推荐
相关产品推荐

