继承和扩展

Odoo 提供了三种不同的机制以模块化的方式来扩展模块:

  • 从已经存在的模型中创建一个新的模型,向副本中添加些新的信息,但是保持源模块原来样子
  • 就地扩展定义在其他模块中的模型,替换之前的版本
  • 将模型的某些字段委托给它所包含的记录

类继承(class inheritance):

  1. 用来添加功能
  2. 新类兼容现有的视图
  3. 存储在同一张表中

原型继承(prototype inhertiance)

  1. 用于拷贝赋值功能
  2. 现有视图忽略新类
  3. 存储在不同的表中

委托继承(Delegation inhertiance)

  1. 可以进行多继承
  2. 现有视图忽略新类
  3. 存储在不同的表中
  4. 新实例将包含一个嵌入的'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})

注意:在使用委托继承中,继承的只有字段,方法不被继承。

原文地址:https://www.cnblogs.com/baishoujing/p/6399147.html