如何阻止保存按钮触发create()方法执行?合作伙伴重复校验问题
Odoo合作伙伴重复检测与阻止创建的方案
一、为什么点击保存仍会弹出警告?
你的onchange方法仅在前端字段变更时触发校验,但Odoo执行create()或write()方法时会走后端逻辑——前端设置的is_exist状态可能未被正确保留,且后端没有基于该字段做校验,导致重复数据检查没覆盖到保存环节。另外,若未给name字段添加唯一约束,后端保存时不会自动拦截重复值,就算前端onchange触发了警告,用户强行操作后后端仍会尝试创建重复数据,进而再次弹出警告。
二、如何阻止保存时触发create()方法?
要彻底拦截重复数据的创建,需在后端create()和write()方法中补充校验逻辑,同时优化前端onchange代码,以下是完整解决方案:
1. 优化前端实时校验
调整onchange方法,去掉对is_exist字段的依赖,同时排除当前记录自身(避免编辑时误判):
@api.onchange('name') def onchange_displayname(self): if self.name: # 编辑时排除当前记录,只查询其他同名数据 is_name_exist = self.search([('name', '=', self.name), ('id', '!=', self.id)], limit=1) if is_name_exist: raise ValidationError(_('合作伙伴名称已存在!'))
2. 重写后端方法拦截创建/修改
在模型中重写create()和write()方法,在数据持久化前做校验,确保前端校验被绕过后,后端仍能拦截:
@api.model def create(self, vals): if vals.get('name'): is_name_exist = self.search([('name', '=', vals['name'])], limit=1) if is_name_exist: raise ValidationError(_('无法创建:合作伙伴名称已存在!')) return super(YourPartnerModel, self).create(vals) def write(self, vals): if vals.get('name'): # 修改时排除当前记录 is_name_exist = self.search([('name', '=', vals['name']), ('id', '!=', self.id)], limit=1) if is_name_exist: raise ValidationError(_('无法修改:合作伙伴名称已存在!')) return super(YourPartnerModel, self).write(vals)
注意将YourPartnerModel替换为你实际使用的模型名称(比如res.partner或自定义模型)。
3. 可选:添加数据库级唯一约束
若要实现最彻底的拦截,可给name字段添加数据库层面的唯一约束,就算代码校验出问题,数据库也会阻止重复数据插入:
class YourPartnerModel(models.Model): _inherit = 'res.partner' # 或你的自定义模型标识 _name = 'your.partner.model' _sql_constraints = [ ('name_unique', 'UNIQUE(name)', '合作伙伴名称必须唯一!'), ]
⚠️ 注意:添加前需确保数据库中已无重复的name值,否则会触发报错。
总结
通过前端onchange实时提示、后端方法拦截、数据库约束兜底的三层校验,既能解决保存时重复弹警告的问题,也能彻底阻止重复合作伙伴的创建。
内容的提问来源于stack exchange,提问作者Nitin Kantak
相关产品推荐
相关产品推荐

