Odoo的開發模式和基本概念
Odoo提供了一個快速開發的框架尤其是比較適合商業場景的一些應用開發,這些應用通常都是對一些業務上的記錄進行一些增刪改查的工作。不僅如此,Odoo還提供了豐富的組件用以制作用戶的交互,如看板、日歷等日常功能。
以下我們分為五個板塊介紹Odoo:
首先,我們整體的對Odoo框架做一個整體的概覽,設置開發環境,并生成自己的第一個Odoo應用;當整體熟悉了 Odoo的主要組件后,我們將深入,更細節地了解Odoo的三層業務架構,這三大板塊分別是模型層、業務邏輯層、和表現層;當我們建立了自己的應用后,最后我們需要測試、發布到一個生產環境并維護。
在這個章節中,我們會快速開始,在未搭建開發環境錢,首先建立Odoo的Web用戶界面。我們將會學習一些關于Odoo架構的東西,幫助我們理解哪些組件比較適合,然后我們會建立一個簡單的圖書館應用,如何在現有模型中增加字段,如何新增新的模型,并為其新增自定義的用戶界面,使其可用。
在我們親身使用開發者模式前,首先在一個更高的層級,看看Odoo的整體架構。
Odoo 架構
Odoo是一個多層的架構,我們看到的主要有一下三層:數據、邏輯和表現層
數據層是最底的一層,它負責數據的存儲和持久化,Odoo使用 PostgreSQLSever來完成這一層工作,PostgreSQL是唯一被支持的關系型數據庫,這是設計者的選擇,其他的數據庫如MySQL等都不受支持,其他諸如文檔、圖像等,通常以文件系統方式存儲。
邏輯層是由Odoo服務器控制,負責所有對數據層的交互。在正常情況下,只允許該層直接訪問數據庫以保證數據安全與同步。在Odoo的核心,有一個ORM(對象關系模型)引擎,ORM提供提供豐富的API以供新增的模塊和數據交互使用。
舉個例子,合作商數據實體,像顧客和供應商,在ORM中作為一個模型,這個模型是一個Python的對象,支持多種的交互方法,例如,create方法可以新建合作商記錄,read方法可以查詢當前的記錄和詳細數據。這些在對象里的方法可以實現特定的業務邏輯,例如create方法可以設置某些默認值或者做某些驗證的規則,read方法可能支持某些字段的計算,為用戶的操作設定不同的權限。
表現層作為展現數據與用戶交互.它是一個負責對所有用戶操作執行的客戶端響應。這個客戶端通過與ORM的API交互去完成讀、寫、驗證或執行其他的一些操作,通過遠程方法調用(RPCS)去呼叫ORM的API方法調用。這些操作會發到odoo服務器做處理,然后將結果返回到客戶端以做進一步處理。
在表現層里,Odoo提供了一個全功能開箱即用的Web客戶端,這個Web客戶端支持業務邏輯需要的所有屬性如:登錄會話,導航菜單,數據列表,表單等等。雖然全局的外觀不像一個前端人員設想的那樣可定制化,但是它已經可以很輕松地區創建一個風格統一的用戶功能模塊。
其中一個補充的顯示層是集成的網站框架,他提供一個完成靈活性的頁面新建可準確地完成用戶的交互。像其他CMS框架一樣,旨在減少一些工作量和技術開發。這個網站框架支持Web控制器實現特定的邏輯代碼,使其余模型內的邏輯保持分離,前段開發人員可以有更大的自由發揮空間。
由于Odoo服務器API的開放性,以致在幾乎所有的平臺和編程語言的客戶端實現也是可行的。利用Odoo的數據和邏輯層實現邏輯,為用戶提供特定的用戶界面,如構建桌面應用程序,手機應用程序。
Odoo還有一個特別的第三方客戶端例子叫ERPpeek,他是一個命令行客戶端。允許你鏈接遠程的Odoo服務器實現交互。這對于有經驗的Odoo開發人員和系統管理員來說,使用它去做服務器上的數據,腳本檢查等高級操作與維護是非常有用的。后續我們將在第8章介紹ERPpeek, 即與其他系統集成外部API。
開發者模式
許多Odoo的自定義都可以直接從用戶界面進行。
這是更改應用程序一個非常快速的方法。它可以做一些小修改,例如增加一個字段,或者做一些較大的自定義,入建立幾個模型,視圖和菜單項。
與后面章節講述的,使用變成工具完成自定義的方式相比,這些通過用戶UI進行的自定義有不少的限制。舉個例子,我們不能添加或擴展ORM的方法,盡管自動化操作可以作為替代方法使用,但他們不容易集成到結構化的開發工作流中,例如運行自動化測試或部署到多個環境中、再如質量保證,預生產和生產。
Odoo10.0的時候引入了Odoo Studio,這是一個應用程序設計器,可以從用戶界面創建并進行定制。我們不在這里討論Odoo Studio, 它雖然是一個用戶體驗友好的前端,但正如我們在本章節中介紹到的,它的自定義會得到相同的限制。Odoo Studio確實包含一個很重要的特性,就是很方便的到處模塊進行定制。這對于高級用戶在SaaS實例或更簡單的自建平臺環境中非常有用。
本書的其余部分將介紹如何以結構化方式對ODOO進行二次開發,用代碼編輯器創建附加模塊。
但在本章中,我們先用開發者模式特性直接在Web用戶界面對界面進行定制,因為對于開發人員來說,了解和使用這些工具是非常重要的。
但更重要的,我們通過這些練習,需要完成一個目標:更好地理解Odoo應用程序的層次結構,以及他們的組件是如何組織的。
廢話不多說,我們開始來折騰這些工具吧。
圖書館項目介紹
我們會用一個簡單的項目來介紹這些開發工具:我們會新建一個簡單的圖書館應用,這個應用主要是幫我們去記錄書本和他們的作者。它可以管理作家的列表和這些書是哪位作家創作的。
我們的圖書館應用需要兩個模型:作家和書本。這兩模型屬于多對多的對應關系:每一個作家可以有多本書,每一本書可以有多個作家。
Odoo已經提供了技術名稱為res.partner內置的伙伴關系模型,以表示人員、組織和地址。例如客戶、供應商、聯系人和應用程序用戶都是合作伙伴。我們使用這個模型用于圖書館應用的作者,將使事情簡單很多。我們只需要在這個模型上增加一個是否為“作家”的標記,以及增加一個僅顯示作家的菜單即可。
而對于書本,我們將創建一個全新的模型,相應的表達,列表視圖以及訪問它們的菜單項。
創建一個工作數據庫
我們需要在一個Odoo測試數據庫上工作。
在第二章(安裝與部署開發環境),我們將會介紹如何通過源碼安裝Odoo,并建立自己的開發環境。在這里我們先略過。我們現在現有的ODOO服務器上直接使用用戶的UI開始。
如果你還沒有一個可用的Odoo已安裝的版本,你可以先在odoo.com建立一個測試數據庫來完成本章節。Odoo.com提供企業版的用戶接口,用戶界面和我們提供的截圖有些許不一致,但這并沒太大問題。要創建一個新的數據庫,你可能會被問到選擇一個啟動應用程序,在這一章中沒有特定的應用程序需要遵循,但如果你不確定選什么,選CRM就可以了。
Odoo遵循一個核心開放的商業模型, 產品分為社區版和企業版兩個版本發布。企業版是在社區版基礎上構建的,它添加了一些高級功能,包括改進的用戶界面。在Odoo.com,你將使用企業版,在公共Github倉庫,你可以找到社區版。雖然這兩個版本外觀看起來不同,但他們只是表面上的改變,兩個版本的用戶界面特性是一樣的
現在,我們通過瀏覽器登錄并進入Odoo的數據庫。對于Odoo在線,地址會如http://<mydbname>.odoo.com。對于自己部署的實例,地址將會是http://<server-address>:8069。8069是Odoo的默認端口,如果你安裝時使用了不同的端口,應修改成對應的端口號。
我們將使用目錄里的應用程序——聯系人,所以我們首先安裝它,如果你還安裝,打開頂部菜單,找到聯系人,點擊安裝。
現在我們可以使用這個實力開始工作了,接下來的一步是激活開發者工具,這讓我們能訪問到Odoo的內部構件。
激活開發者模式
在設置界面的右下角,你可以找到激活開發者模式的鏈接,點擊它,可以在瀏覽器窗口啟用一些開發者模式的特性。
!對于Odoo9.0或之前的版本,開發者模式在用戶菜單下的,“關于”對話框窗口中激活,在網頁界面的右上角
我們還有一個激活開發者模式(帶有資源包)的選項,它所做的是為了防止網頁客戶端壓縮網頁的資源包,這對于調試網頁是非常有用的,犧牲了速度為代價。(下載的文件變大了,自然網頁加載的速度會變慢)
為了加載得更快,Web客戶端會將JavaScript和CSS的資源包進行壓縮,這樣的話,就會對網頁調試帶來不便。激活開發者模式(帶資源包)選項會防止文件壓縮,將網頁資源包單獨的,為被壓縮的加載出來。
TIPS:你也可以不進行設置而啟用開發者模式,只需編輯當前的URL后面加入?debug,或者?debug=assets ,例如,http://myserver/web#home將被更改為http://myserver/web?debug#home。雖然沒用點擊啟用它的連接,但前端框架也支持調試標志,使用?debug=assets 添加到對應的URL來禁止避免對Web前端的資源包進行壓縮。但要注意,導航到其他頁面的時候,這個參數不會進行持久化。
當開啟了開發者模式,我們將會看見有兩個額外的菜單可用:
- Debug菜單,位于頂部菜單右側的Debug圖標,在用戶名和頭像前面。
- 技術菜單條目,在設置應用里
開發人員模式還支持有關表單字段的其他信息,鼠標指針停留在一個字段上時,工具會提示它的技術信息
我們將在下一步部分介紹和使用這些開發者模式的特性。
在一個現有的模型上增加字段
增加一個定制字段是一個很常規的定制操作,可以直接通過用戶UI進行,不需要新增一個自定義模塊。
對于我們的圖書館應用,我們需要增加一個是否為作家的一個字段。作為基礎模型:合作伙伴模型的標記。以此可以列出所有的作家。
我們可以通過“設置”應用來完成這項操作,在 “技術->數據庫結構->模型” 菜單項目,查找到 res.partner 模型,模型描述為“聯系人”的模型。點擊打開相應的表單視圖,你就可以看到合作伙伴模型具體的屬性,包括所有的字段列表:
現在,我們可以在列表在底部點擊新增一行了,這時,一個彈出窗口將會顯示。
讓我們進行一下配置:
- 字段名稱:x_is_book_author
- 字段標簽: Is Book Author?
- 字段類型:布爾值
這個字段必須從x_開始。這時通過UI直接對模型新增字段強制的。對附加模塊沒有這個限制。
就這樣,點擊保存和關閉,我們新的字段就被添加到字段列表里面了。這個模型可能有超過80個字段,你可能需要通過導航翻到下一頁才能看到他,使用列表右上角的向右箭頭即可。
現在,點擊左上角的保存按鈕,保存這些修改。
我們現在新的字段已經對合作伙伴模型可用了,但對于用戶它還是不可見的,因此我們需要將他加入到視圖中。
但是,在合作伙伴或叫聯系人模型表單里,點擊視圖的選項卡,我們可以看到所有定義在res.partner模型上的視圖。你可以看到,每一個視圖是一個數據庫的記錄。修改和增加視圖記錄的結果是,你會在頁面重載的的時候看見它。
在視圖列表中有些重要的事情需要注意。
我們可以看見有多個視圖類型,如表單,樹形,搜索,或者看板。搜索視圖實際上是對右上角搜索欄的可用篩選器定義。其他的視圖類型是不同的數據顯示方式,其中比較基礎的樹形(用于列表視圖)和窗體(用于詳細信息)
樹形和列表都可以用來引用相同的視圖類型,他們實際上是列表,而樹形這個名字是因為歷史的原因。在過去的列表視圖里面曾經有過一個“樹”的層次模型。
如果你通過視圖類型進行排序,你會注意到相同的視圖類型可以有多個定義。實際上,我們可以有幾個基本的視圖定義,如一個空的繼承視圖。我們也可以有多個擴展視圖,例如,將字段添加到現有表單。
擴展視圖可以被其他擴展視圖擴展。在這種情況下,最后的擴展應用于前面的擴展都已應用于基本視圖之后。
對于res.partner模型,我們看到兩種基本的表單形式的客戶端操作:res.partner.form 和 res.partner.simplified.form。想這些操作在菜單項目中,可以指定要使用的特定基視圖,如果沒有任何定義,可以使用序列最少的一個。你可以把它想成默認視圖,單擊視圖行,我們將可以看到帶有的視圖的詳細信息,包括序列值。
要了解用戶界面某一處使用特定的視圖是什么,我們可以使用Debug菜單去檢查它。讓我們去試一試,點擊聯系人,我們會收到一份聯系人名單,點擊任何卡片,將會顯示對應的表單視圖?,F在,我們點擊右上角的調試Debug菜單,選擇“編輯視圖:表單”選項:
這將顯示與我們以前在模型中看到的相同的詳細表單,但是實際上視圖的定位位置,如你所建。它是res.partner.form 頁面視圖
在體系架構方面中,我們可以看到帶有視圖定義XML。我們可以編輯它來添加我們的新字段,雖然這是可行的,但是從長遠來看,這不是一個好方法。這個視圖屬于插件模塊,有時進行模塊升級,這些自定義將會被覆蓋或丟失。我們可以通過外部ID字段,在這種情況下,它是base.view_partner_form。所以我們知道這個視圖是屬于base模塊的。
修改視圖的正確方法是創建集成的視圖擴展。
首先,我們需要從原始視圖中選擇一個元素作為擴展點。我們可以通過檢查基本視圖來選擇一個具有name屬性的XML元素。大多數情況下,這將是一個<field>元素。這里,我們將選擇<field name="category_id" ...>元素。
現在,我們打開Debug菜單,點擊編輯表單頁面選項,選擇繼承的視圖選項卡,點擊底部的“添加明細行”。
彈出窗口會顯示,創建:一個視圖繼承自哪一個?我們將會填寫以下信息:
-視圖名稱:聯系人-自定義是否一個作家
-結構:使用下面的XML:
<field name = "category_id" position="after">
<field name = "x_is_book_author" />
</field>
其他重要的欄目,如模型、視圖類型、及繼承視圖,使用默認值即可。
我們現在保存并關閉。在編輯表單視圖窗口保存然后關閉它。我們可以看到更改已經剩下,然后我們重載這個表單視圖。就是要刷新整個瀏覽器頁面,在大部分的瀏覽器上,我們可以試用快捷鍵F5進行刷新。
增加菜單,模型和視圖
現在我們新增一個應用功能,而不是擴展現有的一個,我們將繼續完成我們的圖書館項目
首先,我們需要新建一個圖書館的頂層菜單,我們現在已經新增了作家菜單條目,下一步,我們將創建一個書本的模型,并且增加一個菜單讓用戶可以試用它,然后我們可以為書本模型創建列表和表單視圖。
創建菜單
現在我們已經有途徑去列出作家,它是一個合作伙伴列表,使用作家標記進去區分。
現在,我們需要新增一個作家菜單使其可以打開這個列表,篩選掉一些不是作家的合作伙伴。一個好消息是,我們可以很簡單的重用了現有的合作伙伴視圖完成這個操作。
在此之前,我們首先要建立一個頂部入口菜單去顯示我們的靚仔圖書館應用,下面將包含作家和書籍兩個菜單。
我們可以在設置里面找到菜單的定制,在“技術”->“用戶界面”-> "菜單項目",使用下面的信息創建一個新的菜單項目:
- 菜單:圖書館
- 上級菜單:(空)
- 動作:(空)
在子菜單選項卡中,點擊增加明細行,新增一下一個子菜單信息如下:
- 菜單:圖書作者
- 上級菜單:圖書館(默認值)
- 動作:選擇 ir.actions.act_window, 在選項列表上右擊創建并編輯,開啟一個對話框去創建關聯的視窗操作。為視窗操作設置以下的值
- 動作名稱: 圖書作者
-
對象: res.partner (目標模型的技術名稱)
1-6.png
保存所有表單的信息,圖書館應用的菜單樹已經可以使用了。
我們重新加載頁面,就可以看到菜單的更改。我們可以看到生成了多級的菜單結構,子菜單項目有關聯的動作,定義它在選中時發生什么。這個動作的名稱將用作呈現視圖的標題。
這里有多種動作可選,最重要的動作為窗口、報表和服務器動作。窗口動作是最常見的視圖,在瀏覽器終端顯示視圖。報表動作是用作運行報表。服務器動作是用作定義自動化任務。
此時,我們關心的是用于顯示視圖操作的窗口動作。
我們剛創建的圖書館作者菜單項使用了一個窗口操作,它是直接從菜單表單創建的,我們可以查看和從設置|技術|動作菜單選項編輯它,在特殊情況下,我們對窗口操作菜單更感興趣。
碰巧我們創建的圖書作者太簡單了,而且確實如此。不要執行我們想要的,它將于所有合作伙伴一起打開一個列表,不管他們是否這本書的作者?集合。我們需要解決這個問題。
打開窗口動作菜單項,查找我們最近創建的圖書作者操作并編輯它,我們關心篩選器的部分,在“常規設置”選項卡內。
TIP:在許多情況下,使用Debug菜單中的Edit Action選項更方便,它提供編輯用于訪問當前視圖窗口操作的便捷快捷方式。
域值字段可以有一個表達式,改表達式定義要顯示的記錄的過濾器,這種“域表達式”遵循特定的odoo語法,后面的章節對此進行解釋,現在我們知道它是一個三胞胎列表就足夠了。
在我們的例子中,我們使用“域值”的表達式是:
| [('x_is_book_author', '=', True)]
為了可用性,我們還想要創建新的記錄有是否作者標記。我們可以在試圖上通過設置默認值操作來完成,這是通過上下文方式完成的,上下文是Odoo傳遞會話信息的方式,包括要使用的默認值。后面幾章將詳細討論它,現在我們只需要知道它是一個鍵值對字典。以default_前綴的值為相應字段提供默認值。
在我們的例子中,上下文值需要的表達式是:
| {'default_x_is_book_author': True}
就是這樣。如果我們現在嘗試Library | Book Authors菜單選項,它應該只列出Is Book Author的合作伙伴?檢查標志,如果有的話。如果我們試著創建一個新的圖書作者,我們會看到那個是圖書作者嗎?默認情況下,復選框將被方便地選中。
我們使用的域過濾器不能被用戶刪除??梢栽O置可以刪除的默認過濾器,使用上下文啟用默認搜索過濾器。這是通過search_default_鍵完成的,如第9章“后端視圖—設計用戶界面”中所述。
創建一個自定義模型
我們現在有一個圖書館的以及菜單,以及有一個作者的菜單項,是時候添加一個圖書菜單去管理圖書的記錄。
讓我們重新查詢,在設置-> 技術->數據結構->模型菜單,點擊新建,填寫模型的信息如下:
- 模型描述:Book
- 模型: x_library_book
我們先保存