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
相关产品推荐
相关产品推荐

