1 2 3 4

10、继承

一、模型继承

模块继承

Odoo提供了两种继承机制以模块化方式扩展现有模型:

 第一种个继承机制允许模块修改在另一个模块中定义的模型:
  •  添加字段到模型中
  •  重写模型上定义的字段
  •  添加约束到模型中
  •  添加方法到模型中
  •  重写现有模型中的方法
 链接:https://www.odoo.com/documentation/10.0/reference/orm.html#inheritance-and-extension
Odoo提供了3种继承机制以模块化方式扩展现有模型:
  • 从现有的模型中创建一个新模型,向副本中添加新信息,但原样保留原始模块
  • 扩展在其他模块中定义的模型,取代以前的版本
  • 委托一些模型的字段给它所包含的记录

经典继承(Classical inheritance):

当我们一起使用 _inherit_name属性时,Odoo创建了一个新的模型,使用现有的模型(通过_继承提供)作为基础。新模型从其基础上获取所有字段、方法和元信息(默认值和al)。

class Inheritance0(models.Model):
    _name = 'inheritance.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 Inheritance1(models.Model):
    _name = 'inheritance.1'
    _inherit = 'inheritance.0'

    def call(self):
        return self.check("model 1")

并使用它们:

 a = env['inheritance.0'].create({'name': 'A'})
 b = env['inheritance.1'].create({'name': 'B'})
 a.call()
 b.call()

会产生:

            "This is model 0 record A"
            "This is model 1 record B"

第二个模型继承了第一个模型的检查方法和名称字段,但是重写了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")

并使用它们:

        env = self.env
        {'name': "A", 'description': "Extended"}

提示:它还将产生各种自动字段,除非它们已被禁用。

 第二个继承机制(委托)允许将模型的每个记录链接到父模型中的记录,并提供对父记录字段的透明访问。
 
 委托(Delegation)
第三种继承机制提供了更大的灵活性(可以在运行时改变),但更少的功能:使用_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})

警告!

当使用委托继承时,方法不是继承的,只能是字段。

 
二、视图继承
Odoo并没有修改现有的视图(通过重写它们),而是提供了视图继承,在这些视图中,子类的“扩展”视图应用于根视图之上,并且可以添加或删除来自其父视图的内容。
扩展视图使用inherit_id字段引用它的父视图,而不是单个视图,它的arch字段由任意数量的xpath元素组成,它们选择并更改其父视图的内容:
<!-- improved idea categories list -->
<record id="idea_category_list2" model="ir.ui.view">
    <field name="name">id.category.list2</field>
    <field name="model">idea.category</field>
    <field name="inherit_id" ref="id_category_list"/>
    <field name="arch" type="xml">
        <!-- find field description and add the field
             idea_ids after it -->
        <xpath expr="//field[@name='description']" position="after">
          <field name="idea_ids" string="Number of ideas"/>
        </xpath>
    </field>
</record>

expr:

在父视图中选择单个元素的XPath表达式。如果匹配不到或匹配多于一个元素,则会引发错误。

position:

应用于匹配元素的操作
    1)inside
          在匹配元素的末尾添加xpath的主体。
    2)replace
          用xpath的主体替换匹配的元素,用原始元素替换新主体中的出现的任何$0节点。
     3)before
          在匹配的元素之前作为成员插入xpath的主体。
     4)after
          在匹配的元素之后作为成员插入xpath的主体。
     5)attributes
          在xpath的主体中使用特殊的属性元素改变匹配元素的属性。
当匹配单个元素时,可以直接在要找到的元素上设置position属性。以下两种继承都将给出相同的结果

<xpath expr="//field[@name='description']" position="after">
    <field name="idea_ids" />
</xpath>

<field name="description" position="after">
    <field name="idea_ids" />
</field>

 练习:

修改当前内容

  • 使用模型继承,修改当前的Partner 模型以添加一个instructor(讲师)布尔字段,以及一个课程时间表中合作伙伴的many2many字段。
  • 使用视图继承,在partner form视图中显示此字段。
 1、创建一个文件openacademy/models/partner.py,并且在__init__.py将文件用import导入
 2、创建一个文件openacademy/views/partner.xml,并且加入到__manifest__.py 
#openacademy/__init__.py
# -*- coding: utf-8 -*-
from . import controllers
from . import models
from . import partner
#openacademy/__manifest__.py
        # 'security/ir.model.access.csv',
        'templates.xml',
        'views/openacademy.xml',
        'views/partner.xml',
    ],
    # only loaded in demonstration mode
    'demo': [
#openacademy/partner.py
# -*- coding: utf-8 -*-
from odoo import fields, models

class Partner(models.Model):
    _inherit = 'res.partner'

    # Add a new column to the res.partner model, by default partners are not
    # instructors
    instructor = fields.Boolean("Instructor", default=False)

    session_ids = fields.Many2many('openacademy.session',
        string="Attended Sessions", readonly=True)
######openacademy/views/partner.xml####注释#####

<?xml version="1.0" encoding="UTF-8"?>
 <odoo>

        <!-- Add instructor field to existing view -->
        <record model="ir.ui.view" id="partner_instructor_form_view">
            <field name="name">partner.instructor</field>
            <field name="model">res.partner</field>
            <field name="inherit_id" ref="base.view_partner_form"/>
            <field name="arch" type="xml">
                <notebook position="inside">
                    <page string="Sessions">
                        <group>
                            <field name="instructor"/>
                            <field name="session_ids"/>
                        </group>
                    </page>
                </notebook>
            </field>
        </record>

        <record model="ir.actions.act_window" id="contact_list_action">
            <field name="name">Contacts</field>
            <field name="res_model">res.partner</field>
            <field name="view_mode">tree,form</field>
        </record>
        <menuitem id="configuration_menu" name="Configuration"
                  parent="main_openacademy_menu"/>
        <menuitem id="contact_menu" name="Contacts"
                  parent="configuration_menu"
                  action="contact_list_action"/>

</odoo>

 

 
 
 
 
 
 
 
 
posted @ 2018-05-04 18:03  I我的博客I  阅读(273)  评论(0)    收藏  举报