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

Odoo14 Python约束未检测计算字段selling_price变更问题求助

Odoo 14 Python约束未触发问题解决

问题核心原因

约束未触发的关键原因有两点:

  1. selling_price是非存储型计算字段(store=False),Odoo的@api.constrains仅在字段被写入数据库时触发,虚拟计算字段不会触发该装饰器。
  2. 监听offer_ids无法触发约束:修改子模型(Offer)的status字段时,父模型的offer_ids字段值(子记录ID列表)并未发生变化,因此不会触发基于offer_ids的约束检查。

解决方案一:将计算字段改为存储型(推荐)

通过设置store=True让计算字段写入数据库,同时修正依赖项和计算逻辑,确保字段更新时触发约束:

1. 修改字段定义

selling_price = fields.Float(readonly=True, copy=False, compute="_compute_selling_price", store=True)

2. 修正计算方法

修正遍历逻辑支持多记录操作,并将依赖项改为offer_ids.status(仅当报价状态变化时重新计算):

@api.depends('offer_ids.status')
def _compute_selling_price(self):
    """When any offer is accepted set selling_price"""
    for record in self:
        accepted_offer = record.offer_ids.filtered(lambda o: o.status == "accepted")
        record.selling_price = accepted_offer[0].price if accepted_offer else 0

3. 优化约束方法

遍历每个记录检查,避免多记录操作时出错:

@api.constrains('selling_price', 'expected_price')
def _check_selling_price(self):
    """Raise Validation Error, if selling_price is lower than 90% of expected price"""
    for record in self:
        if record.selling_price == 0:
            continue  # 无已接受报价时跳过检查
        if float_utils.float_compare(record.selling_price, 0.9 * record.expected_price, precision_digits=2) == -1:
            raise ValidationError("Selling price cannot be lower than 90% of the expected price.")

解决方案二:在报价接受逻辑中直接检查

如果不想修改计算字段的存储属性,可在接受报价的方法中直接添加校验逻辑(更直接):
假设Offer模型中有接受报价的方法,修改如下:

def action_accept_offer(self):
    self.ensure_one()
    # 校验报价是否低于预期价格的90%
    if float_utils.float_compare(self.price, 0.9 * self.property_id.expected_price, precision_digits=2) == -1:
        raise ValidationError("Selling price cannot be lower than 90% of the expected price.")
    # 更新报价状态和父模型售价
    self.status = "accepted"
    self.property_id.selling_price = self.price

内容的提问来源于stack exchange,提问作者tscunami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:40:47