Odoo 11如何在create方法中调用向导?求技术解决方案
在Odoo中实现创建记录前触发向导的方案
我明白你想在创建新记录前先做条件判断,满足条件就弹出向导,否则直接创建——这个需求确实没法直接通过重写create方法实现,因为create方法的返回值必须是当前模型的记录集,不能返回向导视图。不过有几种可行的替代方案,我给你详细拆解:
方案一:前端拦截创建动作(推荐,符合Odoo设计逻辑)
这种方式是在前端层面拦截“新建”按钮的点击事件,先调用后端接口判断条件,再决定是打开向导还是执行默认创建流程。
1. 后端定义条件判断方法
在你的模型中添加一个用于检查条件的方法:
@api.model def check_create_condition(self, vals=None): # 这里写你的条件判断逻辑,比如基于传入的vals、当前用户或系统配置 # 示例:判断当前用户是否属于特定组,或者vals里的某个字段值是否符合要求 return self.env.user.has_group('base.group_system') # 示例条件
2. 前端重写创建逻辑
创建一个JS文件,拦截表单控制器的创建动作:
odoo.define('your_module.custom_create_handler', function(require) { "use strict"; var FormController = require('web.FormController'); FormController.include({ _onCreate: function () { // 调用后端方法检查条件 this._rpc({ model: 'your.model.name', method: 'check_create_condition', args: [this.renderer.state.data], // 传递当前表单填写的临时值 }).then(function(condition_met) { if (condition_met) { // 打开预先定义好的向导动作 return this.do_action('your_module.action_your_wizard'); } else { // 执行默认的创建逻辑 this._super.apply(this, arguments); } }.bind(this)); }, }); });
3. 向导处理完后创建记录
在向导的确认按钮方法中,完成原模型的记录创建:
def action_confirm_wizard(self): # 先处理向导的业务逻辑,比如收集用户输入的额外信息 extra_data = self.your_wizard_field # 获取之前传递的创建参数(可选) default_vals = self.env.context.get('default_create_vals', {}) default_vals['extra_field'] = extra_data # 创建原模型记录 new_record = self.env['your.model.name'].create(default_vals) # 跳转到新创建的记录视图 return { 'type': 'ir.actions.act_window', 'res_model': 'your.model.name', 'res_id': new_record.id, 'view_mode': 'form', 'target': 'current', }
方案二:后端抛出异常触发向导(适合复杂后端逻辑场景)
如果你的条件判断依赖大量后端数据,也可以在create方法中抛出包含向导动作的异常,前端捕获后打开向导。
1. 后端重写create方法
import json from odoo.exceptions import UserError @api.model def create(self, vals): if self._check_create_condition(vals): # 构造向导动作并转为JSON,通过异常传递给前端 wizard_action = self.env.ref('your_module.action_your_wizard').read()[0] # 将创建参数传递给向导 wizard_action['context'] = {'default_create_vals': vals} raise UserError(json.dumps(wizard_action)) else: return super(YourModel, self).create(vals) @api.model def _check_create_condition(self, vals): # 你的条件判断逻辑 return vals.get('amount', 0) > 1000 # 示例条件
2. 前端捕获异常并打开向导
odoo.define('your_module.wizard_exception_handler', function(require) { "use strict"; var Notification = require('web.Notification'); Notification.include({ init: function(parent, options) { // 判断是否是向导动作的异常 if (options.type === 'danger' && options.message.startsWith('{"id":')) { var action = JSON.parse(options.message); parent.do_action(action); // 清空错误信息,不显示错误通知 options.message = ''; } this._super(parent, options); }, }); });
注意事项
- 方案一更符合Odoo的MVC设计模式,前端负责交互逻辑,后端负责业务判断
- 无论哪种方案,都要确保向导处理完成后能正确创建原模型记录,避免用户操作中断
- 可以通过向导的
context传递原创建请求的参数,保证数据连贯性
内容的提问来源于stack exchange,提问作者LALMI Mohamed Lamine
相关产品推荐
相关产品推荐

