1. 程式人生 > >odoo10學習筆記二:繼承(擴充套件)、模組資料

odoo10學習筆記二:繼承(擴充套件)、模組資料

一:繼承

在不改變底層物件的時候新增新的功能——這是通過繼承機制來實現的,作為在現有物件之上的修改層,這些修改可以發生在所有級別:模型,檢視和業務邏輯。不是直接修改現有模組,而是建立一個新模組以新增預期的修改。

1:擴充套件模型

Odoo 模型存在 Python 的模組之外, 在中間登錄檔那裡。對於這個登錄檔,可以通過模型的方法使用self.env[<model name>]進入。 例如, 通過res.partner 模型獲取物件的引用, 程式碼書寫如下 self.env['res.partner']。

 新增欄位:

# -*- coding: utf-8 -*-
from odoo import models, fields, api class Sub(models.Model): _inherit = 'Root' //通過_inherit屬性來繼承父模型 newCol=fields.XX.... //在下面新增新欄位即可。

修改現有欄位:

為了改變現有欄位的屬性,只需再次定義該欄位,需要修改的屬性顯式重寫即可,會保留未修改的所有其他未在此處明確使用的欄位的屬性。

新增方法:

新增新方法很簡單:只需在繼承類中宣告新的函式。

修改方法:

擴充套件或更改現有邏輯,可以通過宣告具有完全相同名稱的方法來覆蓋相應的方法

新方法將替換前一個方法,它可以只是擴充套件繼承類的程式碼,使用Python的super()

方法來呼叫父方法。然後,可以在呼叫super()方法之前和之後,在原有邏輯周圍新增新邏輯。

 擴充套件模型的幾種方式:

1)類繼承:擴充套件類中沒有_name屬性,因為它繼承了父類的_name。對現有模型的擴充套件, 新增新功能,都將新增到現有模型中,不會建立新模型。 因此,在odoo中,根據_name唯一確定這個模型時找到的就是擴充套件後的類。(如上面新增欄位是類繼承)

2)原型繼承:我們想使用具有不同於父模型的值的_name屬性,我們將獲得一個新模型重用來自繼承的特性,但是具有自己的資料庫表和資料。其實就是把繼承的類的功能特性拷貝衣服給新的模型使用,並不改變被繼承模型。

複製意味著被繼承的方法和欄位也將在繼承模型中可用。 對於欄位,這意味著它們也將被建立並存儲在目標模型的資料庫表中。 原始(繼承)和新(繼承)模型的資料記錄保持不相關。 只有定義是共享的。

3)代理繼承(委託繼承):使用_inherits屬性,它允許一個模型以透明的方式包含其他模型。通過字典對映繼承模型與欄位的關係,並關聯它們。(相當於成員變數:引用一個外部的類物件賦值給這個模型的一個成員,但是物件的值是儲存在被引用的類的資料庫表中的。但是在當前類通過成員修改了變數值的,則會同步到被引用的類的資料庫表中)

優點是不需要在幾個表之間重複資料結構,例如地址。 任何需要包含地址的新模型都可以將其委派給嵌入式合作伙伴模型。 如果在合作伙伴地址欄位中引入了修改,則這些修改會立即提供給嵌入它的所有模型!

 

2:擴充套件檢視

表單,列表和搜尋檢視是使用arch XML結構定義的。 要擴充套件檢視,我們需要一種方法來修改這個XML。 這意味著需要定位XML中的元素位置,然後在這些位置引入修改。

對於XML,在其中定位元素的最好方法是使用XPath表示式。如果XPath表示式匹配到多個元素,只有第一個元素會被修改。 因此,表示式應該使用獨特的屬性以使其指定儘可能具體。 使用name屬性是確保我們找到擴充套件點的確切xml元素的最簡單方法。 因此,在我們的檢視XML元素上定義name屬性是很重要的。

Xpath表示式的格式:expr="//標籤名[@屬性]='屬性值'":找到屬性=屬性值的標籤位置。

下面是一個寫在arch中的實現在is_done欄位之前新增date_deadline欄位的具體例子:

<xpath expr="//field[@name]='is_done'" position="before"> //expr屬性值的意思是:找到<filed name="is_done"/>的標籤
       <field name="date_deadline" />
</xpath> 

Odoo為此提供了快捷符號,因此大多數時候我們可以完全避免XPath語法。 我們僅使用要定位的元素的特定屬性及定位型別相關資訊就可以了。

<field name="is_done" position="before">
      <field name="date_deadline" />
  </field> 

如果欄位在同一檢視中多次出現,則應始終使用XPath語法

position屬性是可選的:

after:將內容新增到父元素之中,匹配的節點之後。
before:新增內容在匹配節點之前。
inside(預設值):匹配節點內的追加內容。
replace:替換匹配的節點。如果使用空內容,它將刪除該匹配的元素。
attributes:修改匹配元素的XML屬性。在元素內容使用<attribute name =“attr-name”>實現給屬性name設定新屬性值attr-name。

1)擴充套件表單檢視

<record id="view_form_模組名_inherited" model="ir.ui.view">
       <field name="name">模組名_extension</field>
       <field name="model">模組.資料模型</field>
       <field name="inherit_id" ref="模組_模型.被繼承的form表單name屬性"/>
       <field name="arch" type="xml"> //在arch中進行擴充套件操作:定位—>插入/修改
           <field name="定位標籤位置" position="在標籤的哪裡進行擴充套件">
               <field ......> //擴充套件內容
           </field>
       </field>
</record> 

2)擴充套件列表檢視

<record id="view_tree_模型名_inherited" model="ir.ui.view">
       <field name="name">模型名 extension</field>
       <field name="model">模組.模型</field>
       <field name="inherit_id" ref="被繼承的tree檢視name名"/>
       <field name="arch" type="xml">//在arch中進行擴充套件
            <field name="定位標籤名" position="擴充套件位置"> 
                <field ....進行擴充套件 />
            </field>
       </field>
    </record>

3)擴充套件搜尋檢視

<record id="view_filter_模型名_inherited" model="ir.ui.view">
       <field name="name"> extension</field>
       <field name="model">模型名</field>
       <field name="inherit_id" ref="被繼承的filter檢視名"/>
       <field name="arch" type="xml"> //下面進行定位、擴充套件舉例
           <field name="name" position="after">
               <filter name="filter_my_tasks" string="My Tasks" domain="[('user_id','in',[uid,False])]" />
           </field> 
       </field>
    </record> 

 4)修改記錄

對於記錄:

<record id="x" model="y">

資料記錄載入時,實際上對模型y執行了create或update操作︰ 如果記錄x不存在,則建立它; 否則,更新原來對應的值。 

修改選單項:

< ! — — 修改選單項-->
<record id="選單檢視id" model="ir.ui.menu">
     //進行修改
</record>

修改action_window

<record model="ir.actions.act_window"
    id="action選單id">
       //進行修改
</record>

二:模組資料

1:列表資料的匯出

資料匯出是tree檢視的標準功能,不涉及編碼。

只需在列表檢視左側複選框勾選需要匯出的記錄,然後點選列表上方“動作”下拉列表,選擇“匯出”。

在匯出對話方塊中選擇需要匯出的列、匯出的格式(一般選擇CSV,勾選 匯入相容匯出),然後點選“匯出到檔案”即可。

2:匯入資料

在面板點選“匯入”按鈕,選擇檔案後載入。然後點選“驗證”,檢查檔案內容的格式合法性,如果正常,則點選“匯入”即可。

3:模組資料

模組使用資料檔案,將其配置載入到資料庫,可以通過CSV和XML檔案完成。為了完整性,也可以使用YAML檔案格式,但是它很少用於載入資料。

一個附加的限制是檔名必須與要載入資料的模型的名稱匹配,這樣系統才可以推斷應該將資料匯入相應的模型。

資料CSV檔案的常見用法是載入到ir.model.access模型中的安全定義。

4:演示資料

一個模組在安裝時,儘量事先定義一些演示資料,方便在安裝後進行測試使用。

演示資料我們放在data目錄下,命名為 xx.xx.csv或者xx.xx.xml

然後在manifest檔案中的data屬性進行配置。

5:XML

 noupdate:重複資料載入時,將重寫上次執行中載入的記錄。 這意味著升級一個模組將覆蓋在資料庫內可能已經進行的任何手動更改。此重新匯入行為是預設值,但可以更改,以便在升級模組時,某些資料檔案記錄保持不變。 這是通過<odoo>或元素的noupdate =“1”屬性完成的。 這些記錄將在安裝addon模組時建立,但在後續模組升級中不會對其進行任何操作

XML中定義記錄:

每個<record>元素有兩個基本屬性id和model,並且包含為每列分配值的<field>元素。如前所述,id屬性對應於記錄的外部識別符號,並且模型屬性對應於要寫入記錄的目標模型

設定欄位值的幾種方式如下:

1:<record>元素定義資料記錄幷包含<field>元素以設定每個欄位的值,field元素的name屬性標識要寫入的欄位,要寫入的值是元素內容:欄位的開始和結束標記之間的文字。

2:定義欄位值的更精細的替代方法是eval屬性:它評估一個Python表示式並將結果值分配給欄位。

<field name="date_deadline"
 eval="(datetime.now() + timedelta(-1)).strftime('%Y-%m-%d')" /> 

3:<field>元素還有一個ref屬性,用於使用外部識別符號設定many-to-one欄位的值。

<field name="user_id" ref="base.user_demo" /> 

XML中觸發函式:

可以通過<function>元素,在其載入過程中執行方法。這可以用來建立演示和測試資料。

<function

model="資料模型"

name="資料模型中的方法"

eval="引數" />

另一方式是觸發工作流:

<workflow model="模型"
ref="工作流例項"
action="工作流訊號:觸發工作流" />