Odoo 12:如何重写Tree视图行点击事件以打开指定模型表单
解决Odoo 12中SQL视图Tree行点击跳转指定模型的问题
我之前也碰到过一模一样的场景——SQL视图的Tree能正常展示数据,但点行就报错,因为系统找不到对应的实际模型。这里给你两种实用的解决思路,亲测在Odoo12里有效:
方法一:通过JS重写Tree行点击行为
直接修改Tree视图的默认点击逻辑,让它跳转到你指定的模型记录。
- 先写一个自定义JS模块,重写Tree视图的行点击方法:
odoo.define('your_module.custom_sql_tree', function (require) { "use strict"; var ListView = require('web.ListView'); var core = require('web.core'); ListView.include({ _onRowClicked: function (event) { // 先判断当前视图是不是我们的SQL视图Tree,避免影响其他视图 if (!this.$el.hasClass('sql-view-tree')) { return this._super.apply(this, arguments); } // 阻止默认的错误行为 event.stopPropagation(); // 获取当前行的目标模型ID(比如你要跳转到res.partner,这里取partner_id) var targetRecordId = event.data.record.data.partner_id[0]; // 触发打开目标模型的Form视图 this.do_action({ type: 'ir.actions.act_window', res_model: 'res.partner', // 替换成你要跳转的模型 res_id: targetRecordId, view_mode: 'form', views: [[false, 'form']], target: 'current' }); }, }); return ListView; });
- 在模块的
__manifest__.py里加载这个JS文件:
'assets': { 'web.assets_backend': [ 'your_module/static/src/js/custom_sql_tree.js', ], }
- 最后给你的SQL视图Tree添加专属class,让JS只作用于它:
<tree string="你的SQL视图Tree" class="sql-view-tree"> <field name="name"/> <field name="partner_id"/> <!-- 必须包含目标模型的ID字段 --> <!-- 其他字段 --> </tree>
方法二:创建代理模型关联SQL视图
这种方式更贴合Odoo的原生逻辑,不用写JS,通过一个“假”模型绑定SQL视图,让系统认为它是普通模型:
- 创建代理模型,关联你的SQL视图:
from odoo import models, fields class SQLViewProxy(models.Model): _name = 'sql.view.proxy' _description = 'SQL视图代理模型' _auto = False # 不自动创建数据库表 _table = 'your_sql_view_name' # 替换成你的SQL视图名称 name = fields.Char(string='名称') partner_id = fields.Many2one('res.partner', string='关联伙伴') # 其他和SQL视图对应的字段 # 可选:在这里定义SQL视图的创建语句(如果还没手动创建的话) def init(self): self.env.cr.execute(""" CREATE OR REPLACE VIEW your_sql_view_name AS SELECT row_number() OVER () AS id, p.name, p.id AS partner_id FROM res_partner p -- 你的其他SQL逻辑 """)
- 给这个代理模型配置Tree和Form视图,Form视图可以直接跳转到目标模型:
<!-- Tree视图 --> <record id="view_sql_proxy_tree" model="ir.ui.view"> <field name="name">sql.view.proxy.tree</field> <field name="model">sql.view.proxy</field> <field name="arch" type="xml"> <tree string="代理模型Tree"> <field name="name"/> <field name="partner_id"/> </tree> </field> </record> <!-- Form视图(点击Tree行后打开,这里直接跳转到目标模型) --> <record id="view_sql_proxy_form" model="ir.ui.view"> <field name="name">sql.view.proxy.form</field> <field name="model">sql.view.proxy</field> <field name="arch" type="xml"> <form string="代理模型Form"> <header> <button name="%(action_open_target_partner)d" type="action" string="打开伙伴" class="btn-primary"/> </header> <sheet> <field name="name"/> <field name="partner_id"/> </sheet> </form> </field> </record> <!-- 跳转目标模型的动作 --> <record id="action_open_target_partner" model="ir.actions.act_window"> <field name="name">打开伙伴</field> <field name="res_model">res.partner</field> <field name="view_mode">form</field> <field name="context">{'active_id': partner_id}</field> </record>
这样配置后,点击Tree行就会打开代理模型的Form,再点击按钮就能跳转到目标模型;如果想更直接,也可以在Form视图里设置view_mode直接联动目标模型的视图。
注意点
- 不管用哪种方法,SQL视图里必须包含目标模型的ID字段(比如
partner_id),否则无法定位到要打开的记录。 - 如果用JS方法,记得给目标Tree视图加专属class,避免影响系统其他Tree视图的正常功能。
内容的提问来源于stack exchange,提问作者Ahmed Abd El Latif
相关产品推荐
相关产品推荐

