Odoo 11中存在唯一约束时如何正常使用记录复制功能?
解决Odoo 11中带唯一约束字段的记录复制问题
嘿,这个场景我太熟悉了——给字段加了唯一约束后,默认的复制功能直接撞墙对吧?别担心,咱们完全可以在保留code字段唯一约束的前提下,让复制功能正常工作,核心就是在复制时自动修改新记录的code值,避开原记录的唯一值。下面给你两个实用的方案:
方案一:简单添加复制后缀(快速实现)
最直接的方式就是重写Odoo自带的copy方法,在复制时给原code加上一个标记后缀,比如_copy,这样新记录的code就和原记录不一样了,不会触发唯一约束。
修改你的模型代码如下:
class sample(models.Model): _name = 'sample' code = fields.Char('Code', required=True) name = fields.Char('Name', required=True) _sql_constraints = [ ('code_uniq', 'unique (code)', 'The code must be unique !') ] def copy(self, default=None): default = default or {} # 给原code添加"_copy"后缀,确保新code唯一 default['code'] = f"{self.code}_copy" # 顺便给name也加个标记,方便区分复制记录 default['name'] = f"{self.name} (Copy)" # 调用父类的copy方法完成复制 return super(sample, self).copy(default)
这个方案的好处是代码简单,快速生效,适合对复制后的code格式没有严格要求的场景。
方案二:自动生成递增式唯一code(更专业)
如果希望复制后的code更规整,比如原code是SAM001,复制后自动变成SAM002、SAM003这种递增格式,可以在copy方法里加一段查询逻辑,找到当前最大的同前缀code,然后生成下一个序号:
修改后的模型代码:
class sample(models.Model): _name = 'sample' code = fields.Char('Code', required=True) name = fields.Char('Name', required=True) _sql_constraints = [ ('code_uniq', 'unique (code)', 'The code must be unique !') ] def copy(self, default=None): default = default or {} # 查询所有以原code开头的记录,提取后缀数字 max_suffix = 0 existing_records = self.search([('code', 'like', f"{self.code}_%")]) for rec in existing_records: try: # 拆分code,取最后一段作为后缀数字 suffix = int(rec.code.split('_')[-1]) if suffix > max_suffix: max_suffix = suffix except ValueError: # 如果后缀不是数字,跳过 continue # 生成新的唯一code new_suffix = max_suffix + 1 default['code'] = f"{self.code}_{new_suffix}" default['name'] = f"{self.name} (Copy {new_suffix})" return super(sample, self).copy(default)
这个方案会自动跟踪同前缀code的最大序号,确保每次复制都生成不重复的code,适合有业务规范要求的场景。
额外提示
- 你可以根据自己的业务需求调整
code的生成规则,比如加上日期戳、随机字符串等,只要保证新code唯一即可; - 如果
code是系统自动生成的(比如创建时自动赋值),也可以在copy方法里直接调用生成code的函数,让新记录走一次自动生成流程,这样更符合原有业务逻辑。
内容的提问来源于stack exchange,提问作者Varsha Bolli
相关产品推荐
相关产品推荐

