在 Odoo 中,继承是扩展和修改现有模型(即表)的主要机制。Odoo 提供了两种主要的继承方式:经典继承(Classic Inheritance) 和 代理继承(Delegation Inheritance)。每种方式都有其特点和适用场景。
经典继承(Classic Inheritance)
经典继承类似于面向对象编程中的类继承,它创建了一个新的模型,并且新模型从父模型继承所有字段和方法。这种继承方式不会影响父模型的数据或行为。
特点
- 创建新表:经典继承会在数据库中创建一个新的表。
- 完全独立:新模型和旧模型之间是完全独立的,除非你显式地建立了关系。
- 继承字段和方法:新模型会继承父模型的所有字段和方法,但可以在新模型中覆盖或添加新的字段和方法。
示例
class MyModel(models.Model):
_name = 'my.model'
_inherit = 'res.partner' # 继承 res.partner 模型
new_field = fields.Char('New Field') # 添加新字段
在这个例子中,my.model
是一个全新的模型,它继承了 res.partner
的所有字段和方法,但它们存在于不同的数据库表中。
代理继承(Delegation Inheritance)
代理继承允许一个模型“委托”给另一个模型,从而实现一种多态性。在这种继承方式中,新模型包含对父模型的一个引用,并且可以通过新模型访问父模型的字段和方法,就像这些字段和方法属于新模型一样。
特点
- 共享表:代理继承不会创建新的表,而是通过外键关联到现有的表。
- 自动链接:新模型包含对父模型的引用(通常是
one2many
或many2one
关系),并且可以通过新模型直接访问父模型的字段和方法。 - 数据共享:由于存在引用关系,修改父模型的数据会影响所有相关的新模型实例。
示例
class MyModel(models.Model):
_name = 'my.model'
_inherits = {'res.partner': 'partner_id'} # 代理继承 res.partner 模型
partner_id = fields.Many2one('res.partner', required=True, ondelete='cascade')
new_field = fields.Char('New Field') # 添加新字段
在这个例子中,my.model
模型包含一个 partner_id
字段,它是一个指向 res.partner
模型的外键。你可以通过 my.model
的记录访问 res.partner
的字段和方法,例如:
record = self.env['my.model'].create({
'partner_id': self.env['res.partner'].create({'name': 'Partner Name'}).id,
'new_field': 'Some Value'
})
print(record.name) # 访问 res.partner 的 name 字段
区别总结
特性 | 经典继承 | 代理继承 |
---|---|---|
数据库表 | 创建新表 | 不创建新表,使用现有表 |
独立性 | 完全独立 | 通过外键关联,部分共享 |
字段和方法访问 | 新模型继承父模型的所有字段和方法 | 可以直接访问父模型的字段和方法 |
修改父模型的影响 | 不影响父模型 | 影响所有相关的新模型实例 |
使用场景 | 需要创建完全独立的新模型时 | 需要扩展现有模型并共享数据时 |
选择合适的继承方式
- 经典继承适用于你需要创建一个与原模型完全独立的新模型的情况,特别是当你不想改变原有模型的行为或数据结构时。
- 代理继承适用于你希望扩展现有模型并保持数据共享的情况下,例如当你需要为现有模型添加额外的属性或行为时。