天天看點

Odoo10 開發者文檔(3)--建立一個子產品·

警告

該教程需要 已安裝odoo

開啟/停止Odoo服務

odoo使用用戶端/伺服器架構,用戶端是通過RPC(遠端過程調用協定)通路Odoo服務的web浏覽器。

業務邏輯和擴充通常在伺服器端執行,盡管支援用戶端功能(如,想互動式地圖的新資料表示)可以添加到用戶端。

為了啟動伺服器,在shell内簡單的調用指令Odoo,如果必要添加檔案的完整路徑

伺服器按Ctrl-C兩次從終端停止,或殺死相應的OS程序。

建立一個Odoo子產品

伺服器和用戶端擴充都打包為可選擇的加載在資料庫中的子產品。

Odoo子產品既可以添加新的業務邏輯到Odoo系統,也可以修改和擴充現有的業務邏輯:一個子產品可以被建立為Odoo通用會計支援添加你的國家的會計準則,而下一個子產品,增加了對公車的實時可視化支援。

是以,odoo的一切都随着子產品的開始結束而開始結束。

1.子產品的組成

一個Odoo子產品可以包含多個元素:

業務對象:

聲明為Python的類,這些資源是自動持續的,通過基于配置的Odoo。

資料檔案

XML或CSV檔案聲明中繼資料(視圖或工作流),配置資料(子產品參數化),示範資料和更多

Web controllers

處理Web浏覽器的請求

靜态web資料

Web界面或網站使用的圖檔,CSS或JS檔案

2.子產品結構

每個子產品是子產品目錄内的目錄。子產品目錄通過–addons-path 選項被指定。

提示

大多數指令行選項也可以使用配置檔案來設定

odoo子產品是通過它的manifest聲明的。一個子產品也是一個帶

__init__.py

的Python包,包含子產品中各種Python檔案的導入說明。

例如,如果子產品有一個

mymodule.py

__init__.py

應該包含檔案:

from . import mymodule
           

Odoo提供了一種機制來幫助建立一個新的子產品,odoo-bin有一子指令scaffold 建立一個空的子產品:

odoo-bin scaffold <module name> <where to put it>
           

該指令為子產品建立一個子目錄,并自動為子產品建立一堆标準檔案。其中大部分隻包含注釋代碼或xml。這些檔案的使用将在本教程中解釋。

練習

子產品建立

使用指令行上建立一個空的子產品Open Academy,并安裝在Odoo上。

1. 調用指令odoo-bin scaffold openacademy odoo/addons

2. 将manifest檔案更新到子產品。

3. 不要改變其他檔案。

openacademy/__manifest__.py::

# -*- coding: utf-8 -*-
{
    'name': "Open Academy",

    'summary': """Manage trainings""",

    'description': """
        Open Academy module for managing trainings:
            - training courses
            - training sessions
            - attendees registration
    """,

    'author': "My Company",
    'website': "http://www.yourcompany.com",

    # Categories can be used to filter modules in modules listing
    # Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml
    # for the full list
    'category': 'Test',
    'version': '0.1',

    # any module necessary for this one to work correctly
    'depends': ['base'],

    # always loaded
    'data': [
        # 'security/ir.model.access.csv',
        'templates.xml',
    ],
    # only loaded in demonstration mode
    'demo': [
        'demo.xml',
    ],
}
           
openacademy/__init__.py:

# -*- coding: utf-8 -*-
from . import controllers
from . import models
           
openacademy/controllers.py:

# -*- coding: utf-8 -*-
from odoo import http

# class Openacademy(http.Controller):
#     @http.route('/openacademy/openacademy/', auth='public')
#     def index(self, **kw):
#         return "Hello, world"

#     @http.route('/openacademy/openacademy/objects/', auth='public')
#     def list(self, **kw):
#         return http.request.render('openacademy.listing', {
#             'root': '/openacademy/openacademy',
#             'objects': http.request.env['openacademy.openacademy'].search([]),
#         })

#     @http.route('/openacademy/openacademy/objects/<model("openacademy.openacademy"):obj>/', auth='public')
#     def object(self, obj, **kw):
#         return http.request.render('openacademy.object', {
#             'object': obj
#         })

           
openacademy/demo.xml:

<odoo>
    <data>
        <!--  -->
        <!--   <record id="object0" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 0</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object1" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 1</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object2" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 2</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object3" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 3</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object4" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 4</field> -->
        <!--   </record> -->
        <!--  -->
    </data>
</odoo>

           
openacademy/models.py:

# -*- coding: utf-8 -*-

from odoo import models, fields, api

# class openacademy(models.Model):
#     _name = 'openacademy.openacademy'

#     name = fields.Char()

           
openacademy/security/ir.model.access.csv:

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_openacademy_openacademy,openacademy.openacademy,model_openacademy_openacademy,,,,,

           
openacademy/templates.xml:

<odoo>
    <data>
        <!-- <template id="listing"> -->
        <!--   <ul> -->
        <!--     <li t-foreach="objects" t-as="object"> -->
        <!--       <a t-attf-href="{{ root }}/objects/{{ object.id }}"> -->
        <!--         <t t-esc="object.display_name"/> -->
        <!--       </a> -->
        <!--     </li> -->
        <!--   </ul> -->
        <!-- </template> -->
        <!-- <template id="object"> -->
        <!--   <h1><t t-esc="object.display_name"/></h1> -->
        <!--   <dl> -->
        <!--     <t t-foreach="object._fields" t-as="field"> -->
        <!--       <dt><t t-esc="field"/></dt> -->
        <!--       <dd><t t-esc="object[field]"/></dd> -->
        <!--     </t> -->
        <!--   </dl> -->
        <!-- </template> -->
    </data>
</odoo>


           

3.對象關系映射

Odoo的一個關鍵組成部分是ORM層。這一層可以避免手工編寫大多數SQL并提供了可擴充性和安全性的服務。

業務對象被聲明為Python類擴充模型,該模型将它們內建到自動持久化系統中。

模型可以通過在它們的定義中設定一些屬性進行配置。最重要的屬性是_name,這是必要的,在Odoo中定義系統模型的名字。這裡是一個模型的最小完整定義:

from odoo import models
class MinimalModel(models.Model):
    _name = 'test.model'
           

4.模型檔案

字段用于定義模型可以存儲和在哪裡。字段被定義為模型類的屬性:

from odoo import models, fields

class LessMinimalModel(models.Model):
    _name = 'test.model2'

    name = fields.Char()
           

(1) 共同屬性

就像模型本身一樣,它的字段可以通過将配置屬性作為參數來配置:

一些屬性在所有領域都可用,這裡是最常見的:

string (unicode, default: field's name)

使用者界面中字段的标簽(使用者可見)。

required (bool, default: False)

如果為TRUE,字段不能為空,則必須具有預設值或在建立記錄時始終給予值。

help (unicode, default: '')

Long-form, 為使用者提供了一個幫助提示。

index (bool, default: False)

要求 Odoo建立列上的資料庫索引。

(2) 簡單字段

有兩種類型的字段:“simple”字段,它們直接存儲在模型表中的原子值,以及連接配接記錄(同一模型或不同模型)的“relational”字段。

簡單字段的例子:Boolean, Date, Char.

(3) 保留字段

Odoo在所有模型創造了一些字段。這些字段由系統管理,不應寫入。如果有用或必要,它們可以被讀取:

id (Id)

模型中記錄的唯一辨別符。

create_date (Datetime)

記錄的建立日期.

create_uid (Many2one)

建立記錄的使用者。

write_date (Datetime)

記錄的最後修改日期。

write_uid (Many2one)

最後修改記錄的使用者。

(4) 特殊字段

預設情況下,Odoo所有的模型也需要一個name字段,以便各種顯示和搜尋行為。被用于這些目的的字段能通過設定

_rec_name

重寫。

練習

定義一個模型

在openacademy 子產品裡 定義一個新的資料模型Course ,course 有标題(title)和描述(description) ,必須有标題

編輯openacademy/models/models.py檔案,包含到Course 類中。

openacademy/models.py:

from odoo import models, fields, api

class Course(models.Model):
    _name = 'openacademy.course'

    name = fields.Char(string="Title", required=True)
    description = fields.Text()
           

5.資料字段

雖然使用Python代碼定制行為,但子產品的值的一部分在加載時設定的資料中。

提示

一些子產品的存在隻為資料添加到Odoo。

子產品資料通過資料檔案,帶有

<record>

元素的xml檔案聲明。每個元素建立或更新資料庫記錄。

<odoo>
    <data>
        <record model="{model name}" id="{record identifier}">
            <field name="{a field name}">{a value}</field>
        </record>
    </data>
</odoo>
           

· model是用于記錄Odoo模型名稱。

· id是一個外部辨別符,它允許引用到記錄(而不必知道它的内部資料庫辨別符)。

·

<field>

元素的name是模型中字段的name(例如描述)。他們的body是字段的值。

必須在清單檔案中聲明要加載的資料檔案。它們可以在“data”清單中(總是加載)或在“demo”清單中聲明(僅在示範模式下加載)。

練習

定義示範資料 ,用示範課程建立示範資料,完善課程模式。

編輯openacademy/demo/demo.xml檔案來包含一些資料

openacademy/demo.xml:

<odoo>
    <data>
        <record model="openacademy.course" id="course0">
            <field name="name">Course 0</field>
            <field name="description">Course 0's description

Can have multiple lines
            </field>
        </record>
        <record model="openacademy.course" id="course1">
            <field name="name">Course 1</field>
            <!-- no description for this one -->
        </record>
        <record model="openacademy.course" id="course2">
            <field name="name">Course 2</field>
            <field name="description">Course 2's description</field>
        </record>
    </data>
</odoo>
           
  1. Actions和Menus

    動作和菜單是資料庫中的正常記錄,通常通過資料檔案聲明。動作可以用三種方式觸發:

    (1) 通過點選菜單項(連結到特定的動作)

    (2) 通過點選視圖的按鈕 (如果被連接配接到動作)

    (3) 作為對象的上下文操作

    因為菜單的聲明有點複雜,有一個

    <menuitem>

    快捷方式來更容易地聲明 ir.ui.menu 并連結它到相關的action。
<record model="ir.actions.act_window" id="action_list_ideas">
    <field name="name">Ideas</field>
    <field name="res_model">idea.idea</field>
    <field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_ideas" parent="menu_root" name="Ideas" sequence="10"
          action="action_list_ideas"/>
           

危險

必須在xml檔案的相應菜單前聲明該操作。

資料檔案是按順序執行的,在菜單能建立前,動作的id必須存在于資料庫中

-

練習

定義新的菜單入口

在OpenAcademy 菜單入口定義新的菜單入口來通路課程,使用者應該能夠:

· 顯示所有課程清單

· 建立/修改課程

(1) 建立openacademy/views/openacademy.xml,附帶一個action和觸發action的菜單。

(2) 把它添加到

openacademy/__manifest__.py

的data清單。
openacademy/__manifest__.py

    'data': [
        # 'security/ir.model.access.csv',
        'templates.xml',
        'views/openacademy.xml',
    ],
    # only loaded in demonstration mode
    'demo': [



----------


openacademy/views/openacademy.xml:

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <!-- window action -->
        <!--
            The following tag is an action definition for a "window action",
            that is an action opening a view or a set of views
        -->
        <record model="ir.actions.act_window" id="course_list_action">
            <field name="name">Courses</field>
            <field name="res_model">openacademy.course</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="help" type="html">
                <p class="oe_view_nocontent_create">Create the first course
                </p>
            </field>
        </record>

        <!-- top level menu: no parent -->
        <menuitem id="main_openacademy_menu" name="Open Academy"/>
        <!-- A first level in the left side menu is needed
             before using action= attribute -->
        <menuitem id="openacademy_menu" name="Open Academy"
                  parent="main_openacademy_menu"/>
        <!-- the following menuitem should appear *after*
             its parent openacademy_menu and *after* its
             action course_list_action -->
        <menuitem id="courses_menu" name="Courses" parent="openacademy_menu"
                  action="course_list_action"/>
        <!-- Full id location:
             action="openacademy.course_list_action"
             It is not required when it is the same module -->
    </data>
</odoo>
           

基本視圖

視圖定義顯示模型記錄的方式。每種類型的視圖表示一個可視化模式(一個記錄清單,一個聚合的圖形,…)。視圖可以被要求通過他們的類型(例如類合作夥伴名單)或專門通過它們的ID的通用要求,具有正确的類型和優先級最低的視圖将被使用(是以各類型優先級最低的視圖是預設視圖為型)。

視圖繼承允許改變在别處聲明的視圖(添加或删除内容)。

  1. 通用視圖聲明

    視圖被聲明為ir.ui.view模型的記錄,視圖類型由arch字段的根元素說明:

<record model="ir.ui.view" id="view_id">
    <field name="name">view.name</field>
    <field name="model">object_name</field>
    <field name="priority" eval="16"/>
    <field name="arch" type="xml">
        <!-- view content: <form>, <tree>, <graph>, ... -->
    </field>
</record>
           

危險

視圖的内容是XML.是以,arch字段必須聲明為

type="xml"

,以便正确解析。

2.樹視圖

樹視圖,也被稱為清單視圖。以表單形式顯示記錄。

根元素是

<tree>

,樹視圖的最簡單形式隻列出了表中顯示的所有字段(每個字段列):

<tree string="Idea list">
    <field name="name"/>
    <field name="inventor_id"/>
</tree>
           

3.表單視圖

表單被用于建立和編輯單個記錄。

根元素是

<form>

,它們由高層次結構元素(groups、notebooks)和互動元素(按鈕和字段)組成:

<form string="Idea form">
    <group colspan="4">
        <group colspan="2" col="2">
            <separator string="General stuff" colspan="2"/>
            <field name="name"/>
            <field name="inventor_id"/>
        </group>

        <group colspan="2" col="2">
            <separator string="Dates" colspan="2"/>
            <field name="active"/>
            <field name="invent_date" readonly="1"/>
        </group>

        <notebook colspan="4">
            <page string="Description">
                <field name="description" nolabel="1"/>
            </page>
        </notebook>

        <field name="state"/>
    </group>
</form>
           

練習

使用XML制作form視圖

給Course 對象建立form視圖,資料應該顯示:Course 的name和description。

openacademy/views/openacademy.xml:

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data>
        <record model="ir.ui.view" id="course_form_view">
            <field name="name">course.form</field>
            <field name="model">openacademy.course</field>
            <field name="arch" type="xml">
                <form string="Course Form">
                    <sheet>
                        <group>
                            <field name="name"/>
                            <field name="description"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>

        <!-- window action -->
        <!--
            The following tag is an action definition for a "window action",
           

練習

Notebooks

在Course 表單視圖裡,将“description”字段置于頁籤之下,以便稍後添加其他頁籤,包含附加資訊。

如下修改Course 表單視圖:

openacademy/views/openacademy.xml

                    <sheet>
                        <group>
                            <field name="name"/>
                        </group>
                        <notebook>
                            <page string="Description">
                                <field name="description"/>
                            </page>
                            <page string="About">
                                This is an example of notebooks
                            </page>
                        </notebook>
                    </sheet>
                </form>
            </field>
           

表單視圖也可以使用純HTML來進行更靈活的布局:

<form string="Idea Form">
    <header>
        <button string="Confirm" type="object" name="action_confirm"
                states="draft" class="oe_highlight" />
        <button string="Mark as done" type="object" name="action_done"
                states="confirmed" class="oe_highlight"/>
        <button string="Reset to draft" type="object" name="action_draft"
                states="confirmed,done" />
        <field name="state" widget="statusbar"/>
    </header>
    <sheet>
        <div class="oe_title">
            <label for="name" class="oe_edit_only" string="Idea Name" />
            <h1><field name="name" /></h1>
        </div>
        <separator string="General" colspan="2" />
        <group colspan="2" col="2">
            <field name="description" placeholder="Idea description..." />
        </group>
    </sheet>
</form>
           

4.搜尋視圖

搜尋視圖自定義與清單視圖關聯的搜尋字段(以及其他聚合視圖)。它們的根元素是

<search>

,它們由定義哪些字段可以被搜尋的字段組成:

<search>
    <field name="name"/>
    <field name="inventor_id"/>
</search>
           

如果模型沒有搜尋視圖,Odoo産生一個隻允許用名稱字段檢索的搜尋視圖。

練習

搜尋視圖

允許根據他們的标題或描述來搜尋課程。

openacademy/views/openacademy.xml

            </field>
        </record>

        <record model="ir.ui.view" id="course_search_view">
            <field name="name">course.search</field>
            <field name="model">openacademy.course</field>
            <field name="arch" type="xml">
                <search>
                    <field name="name"/>
                    <field name="description"/>
                </search>
            </field>
        </record>

        <!-- window action -->
        <!--
            The following tag is an action definition for a "window action",

           

模型之間的關系

例如,銷售訂單記錄與包含客戶資料的客戶機記錄有關,它還與銷售訂單線記錄有關。

練習

建立一個session 模型

對于Open Academy 子產品,我們考慮一個session 模型:一個session 是一個給定的時間給定的觀衆在一個給定的時間發生的課程。

建立session 模型。session 具有名稱、開始日期、持續時間和若幹個座位。添加一個動作和菜單項來顯示它們。通過菜單項使新模型可見。

1、在openacademy/models/models.py中建立session 類

2、在openacademy/view/openacademy.xml中給session 對象添加入口

openacademy/models.py


    name = fields.Char(string="Title", required=True)
    description = fields.Text()


class Session(models.Model):
    _name = 'openacademy.session'

    name = fields.Char(required=True)
    start_date = fields.Date()
    duration = fields.Float(digits=(, ), help="Duration in days")
    seats = fields.Integer(string="Number of seats")
           
openacademy/views/openacademy.xml

        <!-- Full id location:
             action="openacademy.course_list_action"
             It is not required when it is the same module -->

        <!-- session form view -->
        <record model="ir.ui.view" id="session_form_view">
            <field name="name">session.form</field>
            <field name="model">openacademy.session</field>
            <field name="arch" type="xml">
                <form string="Session Form">
                    <sheet>
                        <group>
                            <field name="name"/>
                            <field name="start_date"/>
                            <field name="duration"/>
                            <field name="seats"/>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>

        <record model="ir.actions.act_window" id="session_list_action">
            <field name="name">Sessions</field>
            <field name="res_model">openacademy.session</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
        </record>

        <menuitem id="session_menu" name="Sessions"
                  parent="openacademy_menu"
                  action="session_list_action"/>
    </data>
</odoo>
           

注意

digits=(6, 2)指定浮點數的精度:6是數字的總數,而2是小數點後的位數。請注意,它的結果在小數點前是最大值4位數字。

1.關系字段

關系字段連結記錄,包括相同的模型(層次結構)或不同模型之間的連結記錄。

關系字段類型:

(1)

Many2one(other_model, ondelete='set null')

到另一個對象的簡單連結:

(2)

One2many(other_model, related_field)

一個虛拟的關系,一個many2one的逆。一個one2many作為容器的記錄,通路的結果是一個(可能為空)的記錄集:

for other in foo.other_ids:
    print other.name
           

危險

因為One2many 是一個虛拟的關系,在other_model裡必須有一個Many2one字段,name必須是related_field 。

(3)

Many2many(other_model)

雙向多重關系,一方的任何記錄都可以與另一方的任何記錄有關。作為記錄的容器,通路它也會導緻一組可能空的記錄:

for other in foo.other_ids:
    print other.name
           

練習

Many2one 關系

使用Many2one ,修改Course 和Session 模型,反映他們與其他模型的關系:

· course有一個responsible 使用者,該字段的值是内模組化型res.users的一個記錄。

· Session 有一個instructor,該字段的值是内模組化型res.partner的一個記錄。

· 一個session被連接配接到一個course,該字段的值是模型openacademy.course的一個記錄,并且是必須的。

· 更新視圖

添加Many2one字段到模型裡, 并将它們添加到視圖中。

openacademy/models.py

    name = fields.Char(string="Title", required=True)
    description = fields.Text()

    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)


class Session(models.Model):
    _name = 'openacademy.session'

----------
    start_date = fields.Date()
    duration = fields.Float(digits=(, ), help="Duration in days")
    seats = fields.Integer(string="Number of seats")

    instructor_id = fields.Many2one('res.partner', string="Instructor")
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)
           
openacademy/views/openacademy.xml

                    <sheet>
                        <group>
                            <field name="name"/>
                            <field name="responsible_id"/>
                        </group>
                        <notebook>
                            <page string="Description">


----------
           </field>
        </record>

        <!-- override the automatically generated list view for courses -->
        <record model="ir.ui.view" id="course_tree_view">
            <field name="name">course.tree</field>
            <field name="model">openacademy.course</field>
            <field name="arch" type="xml">
                <tree string="Course Tree">
                    <field name="name"/>
                    <field name="responsible_id"/>
                </tree>
            </field>
        </record>

        <!-- window action -->
        <!--
            The following tag is an action definition for a "window action",


----------
                <form string="Session Form">
                    <sheet>
                        <group>
                            <group string="General">
                                <field name="course_id"/>
                                <field name="name"/>
                                <field name="instructor_id"/>
                            </group>
                            <group string="Schedule">
                                <field name="start_date"/>
                                <field name="duration"/>
                                <field name="seats"/>
                            </group>
                        </group>
                    </sheet>
                </form>
            </field>
        </record>

        <!-- session tree/list view -->
        <record model="ir.ui.view" id="session_tree_view">
            <field name="name">session.tree</field>
            <field name="model">openacademy.session</field>
            <field name="arch" type="xml">
                <tree string="Session Tree">
                    <field name="name"/>
                    <field name="course_id"/>
                </tree>
            </field>
        </record>

        <record model="ir.actions.act_window" id="session_list_action">
            <field name="name">Sessions</field>
            <field name="res_model">openacademy.session</field>
           

練習

one2many 逆關系

使用one2many逆關系字段,修改模型,以反映course和session之間的關系

修改course類 ,在course表單視圖添加該字段。

openacademy/models.py


    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)
    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")


class Session(models.Model):
           
openacademy/views/openacademy.xml

                            <page string="Description">
                                <field name="description"/>
                            </page>
                            <page string="Sessions">
                                <field name="session_ids">
                                    <tree string="Registered sessions">
                                        <field name="name"/>
                                        <field name="instructor_id"/>
                                    </tree>
                                </field>
                            </page>
                        </notebook>
                    </sheet>
           

練習

多重many2many 關系

利用關系字段many2many,修改session模型 ,将一組人與每一個課程關聯。出席者将通過夥伴的記錄作為代表,是以我們将與内置的模型res.partner關聯。相應地調整視圖。

修改session類,并添加到表單視圖

openacademy/models.py

    instructor_id = fields.Many2one('res.partner', string="Instructor")
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")
           
openacademy/views/openacademy.xml

                                <field name="seats"/>
                            </group>
                        </group>
                        <label for="attendee_ids"/>
                        <field name="attendee_ids"/>
                    </sheet>
                </form>
            </field>
           

繼承

1.模型繼承

Odoo提供兩繼承機制,以子產品化的方式擴充現有的模型。

第一繼承機制允許子產品修改在其他子產品中定義的模型的行為:

· 添加字段到子產品

· 重寫模型上字段的定義

· 向模型添加限制,

· 向模型添加方法,

· 在模型上重寫現有方法。

第二繼承機制(委托)允許将模型的每個記錄與父模型中的記錄連接配接起來,并提供對父記錄字段的透明通路。

Odoo10 開發者文檔(3)--建立一個子產品·

2.視圖繼承

與其修改現有的視圖(通過重寫他們),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

用于比對元素的操作: