跳至内容

Odoo 18 中的继承类型详解-一篇文章搞懂Odoo的继承机制

Odoo 18 中的继承类型详解

在 Odoo 中,继承机制允许开发者无需修改核心系统即可扩展、修改或定制现有模型、视图和功能。这种模块化设计确保自定义内容在系统升级后仍可维护。Odoo 18 主要提供三种继承类型:Python 继承模型继承视图继承,每种继承类型服务于特定场景,使 Odoo 能够灵活适配各类业务需求。

一、Python 继承(逻辑层继承)

Python 继承用于扩展或重写现有模型的方法和业务逻辑。所有模型默认继承自 Odoo 的基类 models.Model,从而获得基础的 CRUD(创建、读取、更新、删除)功能。

核心特点

  • 方法重写:通过 super() 调用父类方法,在不破坏原有逻辑的前提下添加自定义功能。
  • 应用场景:修改模型的创建、更新逻辑,或添加业务校验规则。

示例:扩展创建方法

新建一个 test.model 模型,名称介绍为测试模型:

from odoo import models, api  

class TestModel(models.Model):  
    _name = "test.model"  
    _description = "测试模型"  

    @api.model  
    def create(self, vals):  
        # 创建记录前添加自定义逻辑(如日志记录、字段预处理)  
        vals['custom_field'] = '默认值'  # 动态设置字段值  
        return super(TestModel, self).create(vals)  # 调用父类创建方法  

上述代码中,create 方法被重写,在创建记录前为 custom_field 设置默认值,同时保留原有创建逻辑。

二、模型继承(数据模型继承)

模型继承用于扩展现有模型的字段或功能,分为三种类型:经典继承扩展继承委托继承

1. 经典继承(Classical Inheritance)

  • 特点:创建新模型,继承父模型的所有字段、方法和元数据,并可新增或重写内容。
    • 使用 _inherit 指定父模型,同时通过 _name 定义新模型名称。
    • 子类完全继承父类行为,可重写方法或添加新字段。
  • 示例:动物与狗的继承关系
    # 父模型:动物  
    class ZooAnimal(models.Model):  
        _name = 'zoo.animal'  
        _description = '动物'  
        name = fields.Char('动物名称')  
    
        def make_sound(self):  
            return "发出声音"  
    
    # 子类:狗(经典继承)  
    class ZooDog(models.Model):  
        _name = 'zoo.dog'  
        _inherit = 'zoo.animal'  # 经典继承,继承父模型  
        _description = '狗'  
    
        def make_sound(self):  
            return f"{self.name} 汪汪叫!"  # 重写父类方法  
    

ZooDog 模型继承自 ZooAnimal,并重写了 make_sound 方法,实现特定行为。

2. 扩展继承(Extension Inheritance)

  • 特点:直接扩展现有模型,无需创建新模型。通过 _inherit 引用目标模型,直接添加字段或修改方法。
    • 不定义 _name,直接作用于原模型,相当于 “Mixin” 机制。
  • 示例:为图书模型添加作者字段
    # 扩展 library.book 模型(原模型由其他模块提供)  
    class ExtendedBook(models.Model):  
        _inherit = 'library.book'  # 扩展原有模型  
        author = fields.Char('作者', default="佚名")  # 新增字段  
    

上述代码为 library.book 模型动态添加 author 字段,原模型的所有实例将自动包含该字段。

3. 委托继承(Delegation Inheritance)

  • 特点:通过关联字段(如 Many2one)实现字段 “继承”,子类可访问父类字段,但不继承方法。
    • 使用 _inherits 参数建立关联,语法为 {'父模型': '关联字段名'}。
    • 子类与父类是独立模型,但子类可通过关联字段透明访问父类字段。
  • 示例:产品变体继承模板字段
    from odoo import fields, models  
    
    # 产品模板(父模型)  
    class ProductTemplate(models.Model):  
        _name = "product.template"  
        _description = "产品模板"  
        name = fields.Char(string='产品名称', required=True)  
        list_price = fields.Float(string='销售价格')  
    
    # 产品变体(委托继承)  
    class ProductProduct(models.Model):  
        _name = "product.product"  
        _inherits = {'product.template': 'product_tmpl_id'}  # 关联字段为 product_tmpl_id  
        product_tmpl_id = fields.Many2one(  
            'product.template',  
            required=True,  
            ondelete="cascade"  # 级联删除  
        )  
        sku = fields.Char(string='SKU')  # 子类特有字段  
    

ProductProduct 通过 product_tmpl_id 关联 ProductTemplate,可直接使用 name 和 list_price 字段,但不会继承 ProductTemplate 的方法。

三、视图继承(界面层继承)

视图继承通过 XPath 表达式修改现有视图,无需直接编辑原始 XML 文件,确保系统升级时自定义内容可保留。

核心机制

  • 使用 inherit_id 指定父视图,通过 xpath 标签定位目标元素。
  • 定位方式:
    1. expr:XPath 表达式,用于匹配视图中的元素(如字段、按钮、容器)。
    2. position:操作方式,包括 after(在目标元素后插入)、before(在目标元素前插入)、replace(替换目标元素)、inside(在目标元素内部插入)。

示例:在销售订单表单添加自定义字段

<record id="sale_order_form_inherit" model="ir.ui.view">  
    <field name="name">sale.order.form.custom</field>  
    <field name="model">sale.order</field>  
    <field name="inherit_id" ref="sale.view_order_form"/>  <!-- 继承原表单视图 -->  
    <field name="arch" type="xml">  
        <!-- 在客户参考号字段后添加内部编号字段 -->  
        <xpath expr="//field[@name='client_order_ref']" position="after">  
            <field name="custom_internal_ref" string="内部编号"/>  
        </xpath>  
    </field>  
</record>  

四、核心对比表

继承类型应用场景关键标识特点
Python 继承扩展/重写模型方法_inherit使用 super() 保留原有逻辑,专注于业务逻辑层的定制。
经典继承创建新模型并继承功能_name + _inherit生成独立子类,支持方法重写和字段扩展,完全继承父模型行为。
扩展继承直接扩展现有模型_inherit无独立模型,直接修改原模型,适用于添加新字段或修改字段属性(Mixin 机制)。
委托继承通过关联字段复用父模型字段_inherits子类与父类独立,通过 Many2one 关联,字段透明访问但不继承方法。
视图继承定制界面布局XML + XPath非破坏性修改,通过 XPath 精准定位元素,支持版本升级兼容。

五、总结

Odoo 的继承机制通过 Python 继承(逻辑层)、模型继承(数据层,含经典/扩展/委托三种模式)和 视图继承(界面层),为开发者提供了从功能逻辑到用户界面的全方位扩展能力。合理使用这些继承类型可确保自定义代码的模块化和可维护性,同时兼容 Odoo 的版本升级。开发者需根据具体场景选择合适的继承方式,避免过度修改核心代码,保持系统的可扩展性和稳定性。

Odoo 18 中的继承类型详解-一篇文章搞懂Odoo的继承机制
中国 Odoo, 苏州远鼎 2025年5月7日
标签
存档