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

Odoo模型与视图委托继承的正确实现及冲突解决

问题

我开发了一个自定义模块,通过partner_id字段以委托继承方式继承res.partner模型,代码如下:

from odoo import fields, models

class CustomModel(models.Model):
    _name = 'custom.model'
    _inherits = {'res.partner': 'partner_id'}
    _description = 'Custom Model'

    partner_id = fields.Many2one(
        comodel_name = 'res.partner',
        ondelete = 'restrict',
        required = True,
        auto_join = True,
        index = True,
    )

其表单视图以primary模式继承基础伙伴表单视图,代码如下:

<record id="custom_model_view_form" model="ir.ui.view">
    <field name="model">custom.model</field>
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="mode">primary</field>
    <field name="priority">20</field>
    <field name="arch" type="xml">
        <!-- customizations in here -->
    </field>
</record>

原本一切正常,但安装website_slides模块后,该模块给res.partner表单添加了自定义按钮/动作,现在每次更新自定义模块都会报错:action_view_courses is not a valid action on custom.model。我尝试调整视图优先级但无效,请问如何正确定义以避免此类冲突,且无需为自定义模型添加伪动作?

解决方案

方法1:重构视图,避免全盘继承res.partner的视图扩展

将视图的mode从primary改为extension,或者直接抛弃对base.view_partner_form的继承,重新构建custom.model的表单视图,只包含需要的res.partner字段和自定义内容:

<record id="custom_model_view_form" model="ir.ui.view">
    <field name="model">custom.model</field>
    <field name="arch" type="xml">
        <form>
            <sheet>
                <div class="oe_title">
                    <h1><field name="name"/></h1>
                </div>
                <group>
                    <field name="email"/>
                    <field name="phone"/>
                    <!-- 按需添加其他res.partner核心字段 -->
                </group>
                <!-- 此处添加自定义模块的字段和布局 -->
            </sheet>
        </form>
    </field>
</record>

这种方式彻底切断了与res.partner视图扩展的关联,自然不会引入website_slides添加的冲突动作按钮。

方法2:在继承视图中移除冲突按钮

如果要保留视图继承模式,可通过XPath定位并移除website_slides添加的action_view_courses按钮:

<record id="custom_model_view_form" model="ir.ui.view">
    <field name="model">custom.model</field>
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="mode">primary</field>
    <field name="priority">20</field>
    <field name="arch" type="xml">
        <!-- 移除冲突的课程动作按钮 -->
        <xpath expr="//button[@name='action_view_courses']" position="replace"/>
        <!-- 自定义内容保留在这里 -->
    </field>
</record>

直接在视图层面剔除不属于当前模型的动作,从根源解决报错。

方法3:模型层代理冲突动作(不推荐)

若不想修改视图,可在custom.model中添加代理方法,将冲突动作转发至关联的partner_id:

def action_view_courses(self):
    return self.partner_id.action_view_courses()

但此方法需为每个冲突动作单独添加代理,维护成本高,仅作为备选方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 16:33:18