Odoo中的模型繼承、視圖繼承、Qweb模板繼承詳解


轉載請注明原文地址:https://www.cnblogs.com/ygj0930/p/10826114.html

 

    在實際開發過程中,經常會遇到需要修改Odoo原生邏輯的情況。然而,直接修改Odoo底層代碼,不利於后面odoo版本迭代時替換。因此,在不改變底層對象的時候添加新的功能,就顯得十分重要。

    Odoo提供繼承機制來實現這個目的,繼承修改可以發生:Python代碼和XML視圖、Qweb模版上

 

一:模型繼承

        1:模型修改

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

      1)添加字段

        如上,直接定義新字段即可。

       2)修改現有字段

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

        3)添加方法

        添加新方法很簡單:只需在繼承類中聲明新的函數。

        4)修改方法

        擴展或更改現有邏輯,可以通過聲明具有完全相同名稱的方法來覆蓋相應的方法

        新方法將替換前一個方法,它可以只是擴展繼承類的代碼,使用Python的super()方法來調用父方法。然后,可以在調用super()方法之前和之后,在原有邏輯周圍添加新邏輯

 

      2:模型繼承的方式

        1)類繼承

         擴展類中沒有_name屬性,因為它繼承了父類的_name。對現有模型的擴展, 添加新功能,都將添加到現有模型中,不會創建新模型。 因此,在odoo中,根據_name唯一確定這個模型時找到的就是擴展后的類。(如上面添加字段是類繼承)

        2)原型繼承(帶name繼承,創建新的表)

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

          復制意味着被繼承的方法和字段也將在繼承模型中可用。 對於字段,這意味着它們也將被創建並存儲在目標模型的數據庫表中。 原始(繼承)和新(繼承)模型的數據記錄保持不相關,只有定義是共享的。

        3)代理繼承(委托繼承)【以成員變量的形式把父類對象包含進來】

          使用_inherits屬性,它允許一個模型以透明的方式包含其他模型。通過字典映射繼承模型與字段的關系,並關聯它們

          通俗解釋:(相當於成員變量:引用一個外部的類對象賦值給這個模型的一個成員,但是對象的值是保存在被引用的類的數據庫表中的。但是在當前類通過成員修改了變量值,則會同步到被引用的類的數據庫表中)

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

 

二:視圖繼承

          表單,列表和搜索視圖是使用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”>實現給標簽設置新屬性值attr-name。
1.如果<attribute></attribute>之間有值,就在匹配的節點上添加以name命名的、以內容主體為值的屬性或是修改原同名屬性值。
2.如果
<attribute></attribute>沒有值,就將匹配節點上名字為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表單id"/>
       <field name="arch" type="xml"> //在arch中進行擴展操作:定位—>插入/修改
           <field name="定位標簽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視圖id"/>
       <field name="arch" type="xml">//在arch中進行擴展
            <field name="定位標簽name" position="擴展位置"> 
                <field ....進行擴展 />
            </field>
       </field>
    </record>

            3)擴展搜索視圖

  <record id="view_filter_模型名_inherited" model="ir.ui.view">
       <field name="name">xxxextension</field>
       <field name="model">模型名</field>
       <field name="inherit_id" ref="被繼承的搜索視圖id"/>
       <field name="arch" type="xml"> //下面進行定位、擴展舉例
           <field name="定位的標簽name" position="after">
               //引入的修改,可以是增加過濾field,也可以定義 filter
           </field> 
       </field>
    </record> 

           

三:Qweb繼承

        Qweb繼承是通過qweb語法來書寫的。但是思路一致:定位——>引入擴展

        Qweb文件繼承分兩種:Qweb視圖類型的文件和data類型的文件,二者繼承修改的方式不同。

     1:視圖類型的qweb文件繼承

       視圖類型的qweb文件,一般定義的都是一些視圖模板,template中的內容大多用html+qweb語句編寫,如widget的視圖定義、odoo中各個界面的定義。

        1)在statc/xml目錄下新建一個xml文件

        2)編寫以下內容

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

<template id="唯一的id" xml:space="preserve">

    <t t-extend="要繼承擴展的template的name屬性值">
        <t t-jquery="使用選擇器來定位" t-operation="相當於position">
            //擴展的內容,一般用html語法+qweb語句編寫
        </t>
    </t>

</template>

         3)在manifest文件中,配置到qweb配置項:

"qweb": [
        "static/src/xml/qweb_file.xml",
    ],

 

     2:data類型的qweb文件繼承

        data類型的qweb文件,一般是一些輔助界面qweb的文件,大多用於定義、引入css文件等,多處於view目錄下。   

        1)在views目錄下新建一個xml文件

        2)編寫以下內容

<?xml version="1.0" encoding="utf-8"?>

<odoo>
    <template id="唯一id" inherit_id="模塊.繼承的templateid">
        <xpath expr="xpath定位語句">
            //引入的內容,一般是link標簽和script標簽,把static/src目錄下的css、js子目錄的文件引入
        </xpath>
    </template>
</odoo>

          3)在manifest文件中配置data,把文件加載

"data": [
        "views/XXX.xml",
    ],

 

                   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM