You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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字段的变化,主动触发主模型的计算字段更新:

  1. 修改子模型的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
  1. 保留主模型原有的计算字段代码(可简化赋值方式):
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:48:22