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

Odoo创建记录前校验One2many字段重复值问题排查

问题根因

现有约束方法无法生效的核心问题有三点:

  • 取值逻辑错误:self.mdm_versions_ids.version是多记录的字段值集合,不是单个版本字符串,无法直接用于重复判断
  • 判断逻辑错误:将版本字符串和One2many记录集对象直接做成员比对,逻辑完全不成立,永远不会触发报错
  • 触发范围不全:仅监听mdm_versions_ids.version,新增/删除One2many行时不会触发校验,存在漏判场景
修复方案

不需要修改create/write方法,直接调整约束方法逻辑即可,修复后完整代码如下:

from odoo import models, fields, api
from odoo.exceptions import ValidationError


class MDMSolutions(models.Model):
    _name = 'mdm.solutions'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = "MDM Versions"
    _rec_name = 'name'

    name = fields.Char('Name', tracking=True, required=True)
    mdm_versions_ids = fields.One2many(
        'mdm.solutions.versions', 'mdm_class_id', string="MDM Versions")

    @api.constrains('mdm_versions_ids', 'mdm_versions_ids.version')
    def check_for_doubles(self):
        for main_record in self:
            # 批量获取当前主记录下所有关联版本号,过滤空值并做去空格处理
            all_versions = main_record.mdm_versions_ids.mapped('version')
            valid_versions = [v.strip() for v in all_versions if v and v.strip()]
            # 比对去重前后长度,存在重复则抛出错误
            if len(valid_versions) != len(set(valid_versions)):
                raise ValidationError("版本号不允许重复,该版本已存在!")


class MDMSolutionVersions(models.Model):
    _name = 'mdm.solutions.versions'
    _rec_name = 'version'

    mdm_class_id = fields.Many2one(
        'mdm.solutions', string="MDM Class")
    version = fields.Char(string="Version", required=True)
逻辑说明
  • 触发范围覆盖全场景:同时监听One2many字段本身、One2many关联行的version字段,新增/删除关联行、修改已有行版本号、从子表入口直接绑定主记录都会触发校验
  • 自动覆盖两类重复场景:同一次操作提交的多条新增记录之间版本号重复、新增记录版本号和数据库已存的历史版本号重复
  • 用ORM内置的mapped()方法批量取字段值,避免逐行遍历的性能损耗,同时解决原代码取值错误的问题
  • 自动过滤空值、处理版本号前后空格的输入误差,减少误判

内容的提问来源于stack exchange,提问作者for-loop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:21:21