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

Odoo 17中基于res.partner子类的自定义视图实现咨询

在Odoo 17中为res.partner扩展类定制独立视图的方案

针对你用传统继承扩展res.partner后,视图交互冲突的问题,有两种可靠的解决方式,根据你的需求场景选择:

方案一:基于上下文+视图优先级的同模型多视图控制

适合不想修改模型继承方式,仅需通过不同入口展示不同字段的场景。核心思路是为每个扩展场景创建独立的继承视图,通过上下文标记控制显示逻辑,并在菜单动作中指定对应视图。

1. 保留原有Python代码

你的扩展类无需修改:

class PartnerExtA(models.Model):
    _inherit = 'res.partner'
    field_a = fields.Char()

class PartnerExtB(models.Model):
    _inherit = 'res.partner'
    field_b = fields.Char()

2. 为每个扩展场景创建独立继承视图

创建两个优先级高于默认视图的继承视图,通过上下文控制字段组的显示:

PartnerExtA专属视图

<record id="view_res_partner_form_ext_a" model="ir.ui.view">
    <field name="name">res.partner.form.ext.a</field>
    <field name="model">res.partner</field>
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="priority" eval="10"/> <!-- 优先级高于默认视图 -->
    <field name="arch" type="xml">
        <!-- 隐藏原有所有字段组 -->
        <xpath expr="//group" position="attributes">
            <attribute name="invisible">1</attribute>
        </xpath>
        <!-- 添加A专属字段组,仅当上下文包含show_ext_a时可见 -->
        <xpath expr="//form" position="inside">
            <group attrs="{'invisible': [('context', 'not in', {'show_ext_a': True})]}">
                <field name="name"/>
                <field name="phone"/>
                <field name="field_a"/>
            </group>
        </xpath>
    </field>
</record>

PartnerExtB专属视图

<record id="view_res_partner_form_ext_b" model="ir.ui.view">
    <field name="name">res.partner.form.ext.b</field>
    <field name="model">res.partner</field>
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="priority" eval="10"/>
    <field name="arch" type="xml">
        <xpath expr="//group" position="attributes">
            <attribute name="invisible">1</attribute>
        </xpath>
        <xpath expr="//form" position="inside">
            <group attrs="{'invisible': [('context', 'not in', {'show_ext_b': True})]}">
                <field name="name"/>
                <field name="phone"/>
                <field name="field_b"/>
            </group>
        </xpath>
    </field>
</record>

3. 创建对应菜单动作,传递上下文

通过菜单动作指定视图和上下文,确保从对应入口打开时加载专属视图:

<!-- Partner Ext A 菜单及动作 -->
<menuitem name="Partner Ext A" id="menu_partner_ext_a" parent="base.menu_partner"/>
<record id="action_partner_ext_a" model="ir.actions.act_window">
    <field name="name">Partner Ext A</field>
    <field name="res_model">res.partner</field>
    <field name="view_mode">form,tree</field>
    <field name="context">{'show_ext_a': True}</field>
    <field name="view_id" ref="view_res_partner_form_ext_a"/>
</record>

<!-- Partner Ext B 菜单及动作 -->
<menuitem name="Partner Ext B" id="menu_partner_ext_b" parent="base.menu_partner"/>
<record id="action_partner_ext_b" model="ir.actions.act_window">
    <field name="name">Partner Ext B</field>
    <field name="res_model">res.partner</field>
    <field name="view_mode">form,tree</field>
    <field name="context">{'show_ext_b': True}</field>
    <field name="view_id" ref="view_res_partner_form_ext_b"/>
</record>

方案二:委托继承(_inherits)创建独立模型

适合需要完全分离模型和视图,避免任何交互冲突的场景。核心是创建新模型,通过_inherits关联res.partner,每个新模型拥有独立的视图体系。

1. 修改Python代码为委托继承

class PartnerExtA(models.Model):
    _name = 'partner.ext.a'
    _inherits = {'res.partner': 'partner_id'}
    partner_id = fields.Many2one('res.partner', required=True, ondelete='cascade')
    field_a = fields.Char()

class PartnerExtB(models.Model):
    _name = 'partner.ext.b'
    _inherits = {'res.partner': 'partner_id'}
    partner_id = fields.Many2one('res.partner', required=True, ondelete='cascade')
    field_b = fields.Char()

2. 为新模型创建独立视图

无需继承默认视图,直接定义专属表单:

<!-- Partner Ext A 表单视图 -->
<record id="view_partner_ext_a_form" model="ir.ui.view">
    <field name="name">partner.ext.a.form</field>
    <field name="model">partner.ext.a</field>
    <field name="arch" type="xml">
        <form>
            <group>
                <field name="partner_id" invisible="1"/> <!-- 隐藏关联字段 -->
                <field name="name"/> <!-- 直接使用res.partner的字段 -->
                <field name="phone"/>
                <field name="field_a"/>
            </group>
        </form>
    </field>
</record>

<!-- Partner Ext B 表单视图 -->
<record id="view_partner_ext_b_form" model="ir.ui.view">
    <field name="name">partner.ext.b.form</field>
    <field name="model">partner.ext.b</field>
    <field name="arch" type="xml">
        <form>
            <group>
                <field name="partner_id" invisible="1"/>
                <field name="name"/>
                <field name="phone"/>
                <field name="field_b"/>
            </group>
        </form>
    </field>
</record>

3. 创建新模型的菜单动作

<menuitem name="Partner Ext A" id="menu_partner_ext_a" parent="base.menu_partner"/>
<record id="action_partner_ext_a" model="ir.actions.act_window">
    <field name="name">Partner Ext A</field>
    <field name="res_model">partner.ext.a</field>
    <field name="view_mode">form,tree</field>
    <field name="view_id" ref="view_partner_ext_a_form"/>
</record>

<menuitem name="Partner Ext B" id="menu_partner_ext_b" parent="base.menu_partner"/>
<record id="action_partner_ext_b" model="ir.actions.act_window">
    <field name="name">Partner Ext B</field>
    <field name="res_model">partner.ext.b</field>
    <field name="view_mode">form,tree</field>
    <field name="view_id" ref="view_partner_ext_b_form"/>
</record>

方案对比

  • 方案一:保留res.partner模型统一性,仅通过入口区分视图,适合需要共享同一数据池的场景。
  • 方案二:完全独立模型,视图无任何冲突,适合需要独立业务流程和数据隔离的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:37:12