如何在Odoo 11的@api.constraint方法中显示双按钮警告弹窗?
在Odoo 11中实现保存时带OK/Cancel按钮的警告弹窗
其实你要的这种带可选按钮的警告,用原生的@api.constraint是做不到的——它的设计逻辑就是一旦触发约束条件,直接抛出异常阻止保存,根本不给用户选择忽略的机会。之前你试的exception.Warning()、osv.except_osv()也都是这个路子,只能弹出提示但没法继续保存;Wizard又需要用户手动触发,不符合保存时自动校验的需求。
我之前做类似需求时,是通过前端拦截保存动作+后端校验逻辑的组合来实现的,完全贴合Odoo原生弹窗样式,步骤如下:
1. 后端写约束校验方法
首先在你的模型里添加一个方法,用来检查需要触发警告的条件:
from odoo import models, api class YourModel(models.Model): _inherit = 'your.model.name' # 替换成你实际的模型,比如sale.order @api.multi def check_save_constraint(self): """检查保存前的约束条件,返回警告信息或无警告""" for record in self: # 这里替换成你的实际校验逻辑,比如检查订单金额是否超限 if record.amount_total > 10000: return { 'warning': True, 'message': '订单金额超过10000元,是否继续保存?' } return {'warning': False}
2. 前端添加保存拦截逻辑
创建一个JS文件(比如static/src/js/save_warning.js),拦截表单的保存动作,先调用后端的校验方法,再弹出原生样式的确认框:
odoo.define('your_module.save_warning', function(require) { "use strict"; var FormController = require('web.FormController'); var core = require('web.core'); var _t = core._t; // 继承原生的表单控制器,重写save方法 FormController.include({ save: function () { var self = this; // 先调用后端的校验方法 return this._rpc({ model: this.modelName, method: 'check_save_constraint', args: [this.getSelectedIds()], }).then(function(result) { if (result.warning) { // 弹出Odoo原生样式的确认框,带OK/Cancel按钮 return self.doConfirm( _t('警告'), _t(result.message), function() { // 用户点击OK,继续执行原保存逻辑 return self._super.apply(self, arguments); }, function() { // 用户点击Cancel,中止保存 return Promise.reject(); } ); } else { // 无警告,直接执行原保存逻辑 return self._super.apply(self, arguments); } }); } }); });
3. 配置模块加载JS文件
在模块的__manifest__.py里添加这个JS文件到后端资产中,确保它能被加载:
{ # 其他配置项... 'assets': { 'web.assets_backend': [ 'your_module_name/static/src/js/save_warning.js', ], }, }
为什么这个方案可行?
- 用Odoo原生的
doConfirm方法弹出弹窗,样式和系统自带的完全一致,不会有违和感; - 拦截了表单的保存动作,在保存前先做校验,符合你的需求;
- 给用户明确的选择:OK继续保存,Cancel中止操作,完美解决你之前的痛点。
内容的提问来源于stack exchange,提问作者LALMI Mohamed Lamine
相关产品推荐
相关产品推荐

