You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Odoo模型字段计算异常:onchange实现除法运算失败

问题分析与解决方案

嘿,我看了你这段Odoo代码,问题出在几个关键地方,让我给你捋一捋:

核心问题点

  • 方法位置错误:你把@api.onchange方法嵌套在了ProductTemplate类的计算方法循环内部,这完全不符合Odoo的模型定义规则!这个onchange方法本应属于sr.sale.price.history模型,Odoo根本识别不到你现在写的这个方法。
  • onchange的触发场景限制:就算你把onchange方法放对位置,它也只在用户在表单界面手动修改字段时触发。而你是通过代码批量调用create创建历史记录的,这种场景下onchange不会自动执行,所以amount_after_disc还是不会被赋值。

推荐解决方案:使用计算字段

因为amount_after_disc是依赖total_priceproduct_uom_qty的派生值,用计算字段是最适合的方案——不管是创建记录还是后续修改依赖字段,都会自动更新计算结果,还能避免手动赋值的遗漏。

修改后的sr.sale.price.history模型代码

class srSalePriceHistory(models.Model):
    _name = 'sr.sale.price.history'
    _description = 'Sale Price History'
    
    name = fields.Many2one("sale.order.line",string="Sale Order Line")
    partner_id = fields.Many2one("res.partner",string="Customer")
    user_id = fields.Many2one("res.users",string="Sales Person")
    product_tmpl_id = fields.Many2one("product.template",string="Template Id")
    variant_id = fields.Many2one("product.product",string="Product")
    sale_order_id = fields.Many2one("sale.order",string="Sale Order")
    sale_order_date = fields.Datetime(string="Order Date")
    product_uom_qty = fields.Float(string="Quantity")
    unit_price = fields.Float(string="Price")
    currency_id = fields.Many2one("res.currency",string="Currency Id")
    total_price = fields.Monetary(string="Total")
    # 改成计算字段,store=True可选(需要存储时添加)
    amount_after_disc = fields.Float(
        string="After Disc", 
        compute='_compute_amount_after_disc', 
        store=True,
        help="Calculated as total_price / product_uom_qty"
    )

    @api.depends('total_price', 'product_uom_qty')
    def _compute_amount_after_disc(self):
        for rec in self:
            # 必须处理除数为0的情况,避免系统报错
            if rec.product_uom_qty != 0 and rec.total_price is not None:
                rec.amount_after_disc = rec.total_price / rec.product_uom_qty
            else:
                rec.amount_after_disc = 0.0

    # 可选:添加onchange方法,在表单编辑时实时预览计算结果
    @api.onchange('total_price', 'product_uom_qty')
    def onchange_amount_after_disc(self):
        if self.product_uom_qty != 0 and self.total_price is not None:
            self.amount_after_disc = self.total_price / self.product_uom_qty
        else:
            self.amount_after_disc = 0.0

额外清理工作

记得把之前嵌套在ProductTemplate类的_get_sale_price_history方法里的那个错误的onchange_field方法删掉,那个位置完全不符合Odoo的开发规范。

关键说明

  • store=True:如果需要在数据库中存储计算值(比如用于筛选、排序或者报表),就保留这个参数;如果不需要存储,每次使用时实时计算,可以去掉。
  • 除数为0的处理:一定要加上这个判断,否则当product_uom_qty为0时会抛出除以0的异常,导致系统崩溃。

内容的提问来源于stack exchange,提问作者Muhammad S. Eltyar

火山引擎 最新活动