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

Odoo 11.0:如何在树形视图显示一对多字段及双模型数据

在Odoo 11.0中实现父模型与One2Many子模型数据同树形视图展示

嗨,我来帮你搞定这个需求!在Odoo 11.0里要把父模型mir.requisition和它的One2Many子模型数据放在同一个树形视图里展示,有两种实用方案,你可以根据自己的场景选择:

方案一:创建虚拟联合模型(推荐,支持平级展示所有数据)

这种方式是通过定义一个不对应真实数据库表的虚拟模型,把父、子模型的数据合并后返回,实现平级展示所有记录。

1. 定义虚拟联合模型

在你的模块的models目录下新建或修改Python文件,添加以下代码:

from odoo import models, fields, api, _

class MirRequisitionCombined(models.Model):
    _name = 'mir.requisition.combined'
    _description = 'Combined Requisition and Lines'
    _auto = False  # 标记为虚拟模型,不创建数据库表

    # 父模型字段
    requisition_id = fields.Many2one('mir.requisition', string='Requisition')
    requisition_name = fields.Char(string='Requisition Name')
    requisition_date = fields.Date(string='Requisition Date')
    # 子模型字段(替换成你实际的子模型字段)
    line_id = fields.Many2one('mir.requisition.line', string='Line')
    product_id = fields.Many2one('product.product', string='Product')
    quantity = fields.Float(string='Quantity')
    # 区分父/子记录的标识
    record_type = fields.Selection([('parent', 'Requisition'), ('child', 'Line')], string='Record Type')

    def init(self):
        # 初始化视图,通过SQL联合查询父、子模型数据
        self.env.cr.execute("""
            CREATE OR REPLACE VIEW mir_requisition_combined AS
            -- 父模型记录
            SELECT 
                id AS id,
                id AS requisition_id,
                name AS requisition_name,
                date AS requisition_date,
                NULL AS line_id,
                NULL AS product_id,
                NULL AS quantity,
                'parent' AS record_type
            FROM mir_requisition
            UNION ALL
            -- 子模型记录
            SELECT 
                (mir_requisition.id * 1000 + mir_requisition_line.id) AS id,  -- 生成唯一ID
                mir_requisition.id AS requisition_id,
                mir_requisition.name AS requisition_name,
                mir_requisition.date AS requisition_date,
                mir_requisition_line.id AS line_id,
                mir_requisition_line.product_id AS product_id,
                mir_requisition_line.quantity AS quantity,
                'child' AS record_type
            FROM mir_requisition_line
            JOIN mir_requisition ON mir_requisition_line.requisition_id = mir_requisition.id
        """)

    @api.model
    def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
        # 重写search_read确保数据正确返回
        if domain is None:
            domain = []
        # 可根据需求添加自定义过滤逻辑
        return super(MirRequisitionCombined, self).search_read(domain, fields, offset, limit, order)

2. 创建联合模型的树形视图

在你的模块的views目录下新建XML文件,添加视图定义:

<odoo>
    <data>
        <record id="view_mir_requisition_combined_tree" model="ir.ui.view">
            <field name="name">mir.requisition.combined.tree</field>
            <field name="model">mir.requisition.combined</field>
            <field name="arch" type="xml">
                <tree string="Combined Requisitions and Lines">
                    <!-- 根据record_type设置不同样式,父记录加粗 -->
                    <field name="record_type" invisible="1"/>
                    <field name="requisition_name" attrs="{'style': 'font-weight: bold;' if record_type == 'parent' else ''}"/>
                    <field name="requisition_date"/>
                    <field name="product_id" attrs="{'invisible': [('record_type', '=', 'parent')]}"/>
                    <field name="quantity" attrs="{'invisible': [('record_type', '=', 'parent')]}"/>
                </tree>
            </field>
        </record>

        <!-- 添加菜单,方便访问这个视图 -->
        <menuitem id="menu_mir_requisition_combined" name="Combined Requisitions" 
                  parent="your_parent_menu_id" action="action_mir_requisition_combined"/>

        <record id="action_mir_requisition_combined" model="ir.actions.act_window">
            <field name="name">Combined Requisitions</field>
            <field name="res_model">mir.requisition.combined</field>
            <field name="view_mode">tree</field>
        </record>
    </data>
</odoo>

注意事项

  • 替换代码中的mir.requisition.line为你实际的One2Many子模型名称
  • 调整init()方法中的SQL字段,确保和你的模型字段完全对应
  • 虚拟模型的ID生成逻辑要保证唯一,示例中用父ID*1000+子ID,你可以根据实际数据量调整

方案二:利用现有树形视图的嵌套展示(简单场景)

如果不需要平级展示,只是希望在父模型的树形视图里直接展开子模型数据,可以直接修改父模型的树形视图,把One2Many字段设置为widget="one2many_list":

<record id="view_mir_requisition_tree" model="ir.ui.view">
    <field name="name">mir.requisition.tree</field>
    <field name="model">mir.requisition</field>
    <field name="arch" type="xml">
        <tree string="Requisitions">
            <field name="name"/>
            <field name="date"/>
            <!-- 直接展示One2Many子模型的字段 -->
            <field name="your_one2many_field" widget="one2many_list">
                <tree>
                    <field name="product_id"/>
                    <field name="quantity"/>
                </tree>
            </field>
        </tree>
    </field>
</record>

这种方式的效果是父记录行下面会有折叠面板,展开后显示对应的子模型数据,适合不需要平级展示的简单场景。

内容的提问来源于stack exchange,提问作者hizbul25

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:44:18