You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 12:如何重写Tree视图行点击事件以打开指定模型表单

解决Odoo 12中SQL视图Tree行点击跳转指定模型的问题

我之前也碰到过一模一样的场景——SQL视图的Tree能正常展示数据,但点行就报错,因为系统找不到对应的实际模型。这里给你两种实用的解决思路,亲测在Odoo12里有效:

方法一:通过JS重写Tree行点击行为

直接修改Tree视图的默认点击逻辑,让它跳转到你指定的模型记录。

  1. 先写一个自定义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;
});
  1. 在模块的__manifest__.py里加载这个JS文件:
'assets': {
    'web.assets_backend': [
        'your_module/static/src/js/custom_sql_tree.js',
    ],
}
  1. 最后给你的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视图,让系统认为它是普通模型:

  1. 创建代理模型,关联你的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逻辑
        """)
  1. 给这个代理模型配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:22:40