Odoo14 Python约束未检测计算字段selling_price变更问题求助
Odoo 14 Python约束未触发问题解决
问题核心原因
约束未触发的关键原因有两点:
selling_price是非存储型计算字段(store=False),Odoo的@api.constrains仅在字段被写入数据库时触发,虚拟计算字段不会触发该装饰器。- 监听
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
相关产品推荐
相关产品推荐

