Odoo表单视图中One2many字段单字段求和存储问题排查
问题原因及解决方案(Odoo One2many子字段变化不触发主模型计算字段更新)
问题原因
你给计算字段total_qty设置了store=True,会把计算结果存储到数据库中,但Odoo的ORM机制是:只有当主模型上被依赖的字段发生直接写操作时,才会重新计算并更新存储型计算字段。
修改One2many子行的quantity字段时,主模型的order_line_ids关联字段本身并没有被修改(只是子记录的字段发生了变化),所以Odoo不会自动触发主模型total_qty字段的重新计算,只有当主模型被保存(比如点击确认按钮触发主记录写操作)时,才会触发compute方法更新存储值。
解决方案
根据你的需求选择以下两种方案:
方案1:不需要存储计算结果(实时显示)
直接去掉store=True,让total_qty成为纯计算字段,视图会在子行quantity变化时实时计算并显示结果:
total_qty = fields.Integer( string="Total Quantity", readonly=True, track_visibility='onchange', compute='_compute_total_qty' ) @api.depends('order_line_ids.quantity') def _compute_total_qty(self): for record in self: record.total_qty = sum(line.quantity for line in record.order_line_ids)
方案2:必须存储计算结果(支持搜索/报表等场景)
如果需要把total_qty存储到数据库,需要在子模型(对应order_line_ids的模型)中,监听quantity字段的变化,主动触发主模型的计算字段更新:
- 修改子模型的
write方法,当quantity被修改时,强制主模型重新计算并写入数据库:
class OrderLine(models.Model): _name = 'order.line' # 替换为你的子模型实际名称 _description = 'Order Line' quantity = fields.Integer(string="Quantity") order_id = fields.Many2one('order.detail', string="Order") # 替换为你的主模型实际名称 def write(self, vals): res = super().write(vals) # 当quantity字段被修改时,触发主模型计算 if 'quantity' in vals: self.order_id._compute_total_qty() self.order_id.flush() # 强制将计算结果写入数据库 return res
- 保留主模型原有的计算字段代码(可简化赋值方式):
total_qty = fields.Integer( string="Total Quantity", readonly=True, store=True, track_visibility='onchange', compute='_compute_total_qty' ) @api.depends('order_line_ids.quantity') def _compute_total_qty(self): for record in self: record.total_qty = sum(line.quantity for line in record.order_line_ids)
内容的提问来源于stack exchange,提问作者Đỗ Tùng Lâm
相关产品推荐
相关产品推荐

