Odoo 17向导树视图按钮点击报错:请先点击保存按钮
Odoo 17 产品捆绑向导按钮未触发后端方法问题解决
问题核心原因
- 必填字段缺失导致无法保存:向导主模型
sh.product.bundle.wizard的sh_bundle_id字段标记为required=True,但视图中被注释隐藏,导致向导处于未完成状态,无法保存,客户端触发“请先点击保存”提示。 - 按钮模型关联错误:树视图中的
action_addBundle按钮定义在子模型sh.product.bundle.wizard.line的视图中,但方法实际定义在主模型sh.product.bundle.wizard上,Odoo无法找到对应方法,同时未保存的主记录也会阻止操作。
分步解决方案
步骤1:修复必填字段问题
选择以下两种方式之一:
方式A:在视图中显示必填字段
修改向导视图,取消sh_bundle_id字段的注释:
<group> <field name="sh_partner_id" /> <field name="sh_bundle_id" /> </group>
方式B:移除模型字段的必填属性
修改向导主模型代码:
sh_bundle_id = fields.Many2one( 'product.template', 'Add Pack / Bundle', domain=[('sh_is_bundle', '=', True)] ) # 去掉required=True
步骤2:调整按钮位置与方法关联(二选一)
方案A:将按钮移至主表单区域(批量添加所有捆绑产品)
适合一次性将所有向导行产品同步到销售订单的场景:
- 修改向导视图,将按钮从树视图中移至页面顶部:
<page string="Products"> <button name="action_addBundle" string="Add All Bundles to Order" type="object" icon="fa-exchange" class="btn-primary" /> <field name="sh_bundle_lines"> <tree editable="bottom" create="0"> <field name="sh_product_id" readonly="1" /> <field name="sh_bundle_quantity" force_save="1" readonly="1"/> <field name="sh_bundle_uom" force_save="1" readonly="1"/> </tree> </field> </page>
- 完善主模型的
action_addBundle方法,实现同步逻辑:
def action_addBundle(self): sale_order_id = self._context.get('active_id') sale_order = self.env['sale.order'].browse(sale_order_id) if sale_order and self.sh_bundle_lines: order_lines = [] for line in self.sh_bundle_lines: order_lines.append((0, 0, { 'product_id': line.sh_product_id.id, 'product_uom_qty': line.sh_bundle_quantity or 1.0, 'price_unit': line.sh_product_id.list_price, 'name': line.sh_product_id.display_name, })) sale_order.write({'order_line': order_lines}) # 关闭向导 return {'type': 'ir.actions.act_window_close'}
- 确保打开向导时传递销售订单ID,修改销售订单模型的
action_bundle_product:
def action_bundle_product(self): if self: return { 'name': 'Add Pack/Bundle', 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'sh.product.bundle.wizard', 'target': 'new', 'context': { 'default_sh_partner_id': self.partner_id.id, 'active_id': self.id, 'active_model': 'sale.order', }, }
方案B:保留树视图按钮(单行单独添加)
需要将方法定义在子模型上,实现单行产品同步:
- 修改子模型代码,添加
action_addBundle方法:
from odoo import models, fields, api class ShProductBundleWizardLine(models.TransientModel): _name = 'sh.product.bundle.wizard.line' _description = 'Bundle Wizard Lines' wizard_id = fields.Many2one('sh.product.bundle.wizard', 'Wizard ID') sh_product_id = fields.Many2one('product.product', 'Product', required=True) sh_bundle_quantity = fields.Float("Quantity", default=1.0) sh_bundle_uom = fields.Many2one("uom.uom", "Unit Of Measure", related="sh_product_id.uom_id", readonly=True) def action_addBundle(self): sale_order_id = self.env.context.get('active_id') sale_order = self.env['sale.order'].browse(sale_order_id) if sale_order: sale_order.write({ 'order_line': [(0, 0, { 'product_id': self.sh_product_id.id, 'product_uom_qty': self.sh_bundle_quantity, 'price_unit': self.sh_product_id.list_price, 'name': self.sh_product_id.display_name, })] }) return {'type': 'ir.actions.act_window_close'}
- 修改向导视图的按钮,确保上下文传递销售订单ID:
<button name="action_addBundle" string="Add to Order" type="object" icon="fa-plus" context="{'active_id': parent.active_id}"/>
- 同样需要修改销售订单模型的
action_bundle_product,传递active_id(同方案A的步骤3)。
验证测试
- 升级模块后,打开销售订单,点击「Add Pack/Bundle」按钮打开向导。
- 确保必填字段已填写(如果保留
sh_bundle_id必填)。 - 点击对应按钮,检查销售订单行是否成功添加产品。
内容的提问来源于stack exchange,提问作者Ishfaq Babar
相关产品推荐
相关产品推荐

