Odoo 提供了三种不同的机制以模块化的方式来扩展模块:
- 从已经存在的模型中创建一个新的模型,向副本中添加些新的信息,但是保持源模块原来样子
- 就地扩展定义在其他模块中的模型,替换之前的版本
- 将模型的某些字段委托给它所包含的记录
类继承(class inheritance):
- 用来添加功能
- 新类兼容现有的视图
- 存储在同一张表中
原型继承(prototype inhertiance)
- 用于拷贝赋值功能
- 现有视图忽略新类
- 存储在不同的表中
委托继承(Delegation inhertiance)
- 可以进行多继承
- 现有视图忽略新类
- 存储在不同的表中
- 新实例将包含一个嵌入的'obj1'实例,其值是同步的。
古典继承(Classical inheritance)
当_name与_inherit一起使用时,Odoo使用已经存在的模型作为base(通过_inherit),创建一个新的模型。这个新模型将从它的base中获得所有的字段,方法和元信息。
class Inheritance0(models.Model): _name='inhertiance.0' name=fields.Char() def call(self): return self.check("model 0") def check(self,s): return "This is {} record {}".format(s,self.name) class Inhertiance1(models.Model): _name='inheritance.1' _inherit='inheritance.0' def call(sefl): return self.check("model 1")
使用它们:
a = env['inheritance.0'].create({'name': 'A'}) a.call() b = env['inheritance.1'].create({'name': 'B'}) b.call()
产生结果:
This is model 0 record A This is model 1 record B
第二个模型继承了第一个模型的check方法和name字段,但是覆盖了call方法,像是使用了Python标准继承时一样。
扩展(Extension)
当使用_inherit而忽略_name时,这新模型将替代这个已经存在的模型,本质上是就地进行扩展。这有利于添加一些新的字段或者方法到已经存在的模型上(被其他模块创建),或者自定义,重新配置它们(例如修改他们的默认排序)。
class Extension0(models.Model): _name='extension.0' name=fields.Char(default="A") class Extension1(models.Model): _inherit='extension.0' description=fields.Char(default="Extended")
record=env['extension.0'.create([])] record.read()[0]
产生结果:
{'name': "A", 'description': "Extended"}
委托(Delegation)
第三种继承机制提供了更多地灵活性(它可以在运行的时候被更改),但是效率不高(less power)。使用_inherits的模型将任何不在当前模型的字段查找委托"children"模型。这个委托通过引用字段(设置在父模型上)自动执行:
class Child0(models.Model): _name = 'delegation.child0' field_0 = fields.Integer() class Child1(models.Model): _name = 'delegation.child1' field_1 = fields.Integer() class Delegating(models.Model): _name = 'delegation.parent' _inherits = { 'delegation.child0': 'child0_id', 'delegation.child1': 'child1_id', } child0_id = fields.Many2one('delegation.child0', required=True, ondelete='cascade') child1_id = fields.Many2one('delegation.child1', required=True, ondelete='cascade')
record = env['delegation.parent'].create({ 'child0_id': env['delegation.child0'].create({'field_0': 0}).id, 'child1_id': env['delegation.child1'].create({'field_1': 1}).id, }) record.field_0 record.field_1
产生结果:
0
1
也可以像这样在委托的字段上直接写入:
record.write({'field_1': 4})
注意:在使用委托继承中,继承的只有字段,方法不被继承。