第一章 使用開(kāi)發(fā)者模式快速入門(mén) Odoo 15
Odoo提供了一個(gè)快速應(yīng)用開(kāi)發(fā)框架,尤其適合構(gòu)建商業(yè)應(yīng)用。這類(lèi)應(yīng)用通常用于保存業(yè)務(wù)記錄和工作流。Odoo 不僅簡(jiǎn)化了這類(lèi)應(yīng)用的構(gòu)建,還提供了看板、日歷、圖表等視圖的豐富組件,用于創(chuàng)建難以抗拒的用戶(hù)界面。
本章我們直接進(jìn)入實(shí)操,通過(guò)web 界面進(jìn)行編碼一探Odoo 的內(nèi)部,這甚至都不需要配置本地開(kāi)發(fā)環(huán)境。這樣會(huì)讓我們直觀地感受 Odoo 應(yīng)用所涉及到的組件。同時(shí),我們還會(huì)了解一些查看已有應(yīng)用及快速構(gòu)建原型的基本工具。
本文主要內(nèi)容有:
to-do (任務(wù)清單)應(yīng)用
掌握 Odoo 的基礎(chǔ)結(jié)構(gòu)
使用 Odoo SaaS 測(cè)試庫(kù)
在服務(wù)器上安裝 Odoo
激活開(kāi)發(fā)者模式
對(duì)模型添加自定義字段
新建模型
創(chuàng)建菜單項(xiàng)及動(dòng)作
配置訪問(wèn)控制權(quán)限
創(chuàng)建視圖
學(xué)習(xí)完本章,讀者會(huì)熟悉 Odoo 自定義和開(kāi)發(fā)的主要組成部分。
技術(shù)準(zhǔn)備
學(xué)習(xí)本章至少要求有一個(gè)現(xiàn)代瀏覽器,如 Firefox 或 Chrome。有瀏覽器并且可以聯(lián)網(wǎng),就可以通過(guò) Odoo SaaS測(cè)試庫(kù)學(xué)習(xí)本章,無(wú)需進(jìn)行本地安裝。
當(dāng)然讀者也可以使用本地安裝的 Odoo 實(shí)例。可以參見(jiàn)在服務(wù)器上安裝 Odoo一節(jié),其中講解了 Windows、Ubuntu 和紅帽企業(yè)版 Linux(RHEL)上安裝預(yù)打包版本。此外,還可以使用 Docker 安裝。
引入 to-do 清單應(yīng)用
本章中我們會(huì)使用一個(gè)示例項(xiàng)目來(lái)演示所講解的概念。這個(gè)項(xiàng)目就是一個(gè)簡(jiǎn)單的 to-do清單 Odoo應(yīng)用。
使用這個(gè)應(yīng)用我們可以新增清單,然后標(biāo)記完成。比如可在項(xiàng)目中添加買(mǎi)雞蛋,然后在購(gòu)買(mǎi)后勾選已完成。并且To-do 清單應(yīng)僅對(duì)用戶(hù)自己可見(jiàn),因而當(dāng)前用戶(hù)僅能獲取自己的 to-do 列表。為了增加點(diǎn)趣味性,我們添加了一些復(fù)雜功能,允許 to-do清單包含一組和任務(wù)相關(guān)的用戶(hù),即工作小組。
就該應(yīng)用我們應(yīng)考慮以下幾層:
數(shù)據(jù)層:通過(guò)模型實(shí)現(xiàn)
業(yè)務(wù)邏輯層:通過(guò) Pyhon自動(dòng)化編碼實(shí)現(xiàn)
展示層:通過(guò)視圖實(shí)現(xiàn)
對(duì)于數(shù)據(jù)層,我們需要一個(gè) To-do 清單模型,我們還將利用內(nèi)置的 Contact(也稱(chēng)之為 Partner)模型來(lái)支持工作組的功能。當(dāng)然還要記得在新的模型中配置訪問(wèn)權(quán)限。
業(yè)務(wù)邏輯層中我們使用框架處理增刪改查(CRUD)基本操作。本例中我們無(wú)需使用額外的自動(dòng)化支持。我們需要在開(kāi)發(fā)者模塊中使用 Python 代碼來(lái)使用自動(dòng)化功能。我們暫不需要在開(kāi)發(fā)的模板中使用,但可以在 Technical 菜單下的 Automated Actions 工具來(lái)通過(guò) UI 界面實(shí)現(xiàn)這種業(yè)務(wù)邏輯。在本章后面的例子中會(huì)進(jìn)行使用。
最后在展示層中我們將為應(yīng)用添加菜單項(xiàng),以及 to-do 模型的視圖。業(yè)務(wù)應(yīng)用的基本視圖是用于查看已有記錄的列表視圖、深入查看記錄詳情的表單視圖。為增強(qiáng)易用性,我們還可以在列表視圖的搜索框中預(yù)置過(guò)濾項(xiàng)。搜索選項(xiàng)通過(guò)搜索視圖組件進(jìn)行實(shí)現(xiàn)。
以下是創(chuàng)建 to-do 列表應(yīng)用的步驟
新建 to-do 清單模型
創(chuàng)建菜單項(xiàng)并讓其對(duì)用戶(hù)可見(jiàn)
配置訪問(wèn)控制權(quán)限
為 to-do 清單創(chuàng)建列表和表單視圖
新增的 to-do 清單模型包含如下字段
Description: 字符 類(lèi)型
Is Done?標(biāo)記:布爾型
應(yīng)用的具體功能包含團(tuán)隊(duì)功能:即可添加執(zhí)行同一任務(wù)的一組用戶(hù)。因此需要一個(gè)表示用戶(hù)的模型。Odoo 自帶就有Contact模型( 技術(shù)名稱(chēng)為res.partner),可用于存儲(chǔ)個(gè)人、公司和地址。
任務(wù)清單模型應(yīng)當(dāng)包含一個(gè)工作團(tuán)隊(duì)字段,可用于選擇一組用戶(hù)。我們希望僅有指定的人可被選擇加入工作團(tuán)隊(duì)。因此我們需要修改 Contact 模型添加Is Work Team?標(biāo)記。僅帶有此標(biāo)記的用戶(hù)可添加至工作團(tuán)隊(duì)。
為實(shí)現(xiàn)工作團(tuán)隊(duì)的功能,我們需要向Contact 模型和表單視圖添加一個(gè)字段。在進(jìn)入實(shí)施之前,我們先討論一些與 Odoo 框架相關(guān)的功能,然后學(xué)習(xí)如何準(zhǔn)備要使用的環(huán)境。
理解 Odoo 的基本概念
對(duì)一初學(xué) Odoo 的人可能有些概念不是那么一目了然。我們?cè)趯W(xué)習(xí)之前先進(jìn)行掌握。
有關(guān) Odoo 和 Odoo 社區(qū)
Odoo 是一個(gè)是 Fabien 在比利時(shí)所創(chuàng)建的Odoo SA 公司所發(fā)布的軟件產(chǎn)品。Odoo 軟件產(chǎn)品是由公司主導(dǎo)的,也就是說(shuō)路線圖及開(kāi)發(fā)都由 Odoo SA 緊緊控制在手里。但同時(shí)又遵循開(kāi)源的條例,歡迎社區(qū)貢獻(xiàn)代碼。
Odoo 軟件采取開(kāi)源內(nèi)核的商業(yè)模式,也就是說(shuō)部分代碼是開(kāi)源的、部分是自有產(chǎn)權(quán)?;谶@一模式,Odoo 發(fā)布了兩個(gè)版本。
社區(qū)版(CE)對(duì)外公開(kāi)、開(kāi)源,使用 LGPL 開(kāi)源證書(shū)。
企業(yè)版(EE)僅對(duì)官方合作伙伴及持有專(zhuān)有證書(shū)的顧客開(kāi)放,采取閉源代碼。
Odoo EE是 Odoo CE 內(nèi)核上層的一堆模塊,提供一些可誘使用戶(hù)升級(jí)的高級(jí)功能。Odoo EE的收入為Odoo CE及Odoo EE的開(kāi)發(fā)提供資金來(lái)源。Odoo創(chuàng)始人及 CEO Fabien Pinckaers 反復(fù)承諾會(huì)將80%的代碼放到社區(qū)版里開(kāi)源,另20%放到自有的企業(yè)版中。
任何開(kāi)源項(xiàng)目的最大資源都是圍繞其的社區(qū)。Odoo 有很多活躍的開(kāi)源貢獻(xiàn)者。對(duì)于 Odoo 這個(gè)產(chǎn)品,社區(qū)貢獻(xiàn)了功能反饋、翻譯、安全問(wèn)題報(bào)告、bug 修復(fù)并且偶爾會(huì)對(duì)內(nèi)核產(chǎn)品進(jìn)行一些技術(shù)改進(jìn)。Odoo CE 的地址為https://github.com/odoo/odoo。
除了 Odoo 的內(nèi)核產(chǎn)品外,社區(qū)還發(fā)布一些新功能模塊。很多 Odoo 社區(qū)內(nèi)的個(gè)人及公司將他們的 Git 倉(cāng)庫(kù)以開(kāi)源證書(shū)向公眾開(kāi)放。他們也會(huì)在 Odoo 的官方商店?Odoo Apps?上發(fā)布應(yīng)用。應(yīng)用商店中可發(fā)布免費(fèi)及付費(fèi)模塊。
Odoo 的內(nèi)核項(xiàng)目中不會(huì)添加這些社區(qū)模塊,因此社區(qū)模塊以分散的形式開(kāi)發(fā),沒(méi)有共同的標(biāo)準(zhǔn)及品控。Odoo 社區(qū)聯(lián)盟(OCA)的成立就是為了解決這一問(wèn)題。它納入了這些社區(qū)貢獻(xiàn)的模塊,并提供了通用代碼標(biāo)準(zhǔn)、指南、品控及工作流工具。OCA 的代碼倉(cāng)庫(kù)位于https://github.com/OCA,可以在https://odoo-community.org/shop查看這些發(fā)布的模塊。
Odoo 產(chǎn)品的版本
在編寫(xiě)本書(shū)時(shí),Odoo 的最新穩(wěn)定版是 Odoo 15,在 GitHub 上的分支為15.0。這是在全書(shū)中使用的版本。Odoo 的大版本按年發(fā)布,每年10月在 Odoo 體驗(yàn)大會(huì)上進(jìn)行發(fā)布。
官方支持最新的三個(gè)穩(wěn)定版。發(fā)布版本15后,對(duì)13和14版本仍提供支持,但版本12就不再進(jìn)行官方支持了。也就是說(shuō)不再進(jìn)行漏洞及安全問(wèn)題修復(fù)了。
Odoo 的大版本之間數(shù)據(jù)庫(kù)是不兼容的。如果在 Odoo 15的服務(wù)端運(yùn)行此前大版本中創(chuàng)建的數(shù)據(jù),不會(huì)跑通。要在更新的 Odoo 版本中使用老數(shù)據(jù)庫(kù)需要進(jìn)行頗為費(fèi)力的遷移。
對(duì)于插件模塊也是如此。通常在一個(gè)大版本中開(kāi)發(fā)的 Odoo 插件在另一個(gè)大版本中無(wú)法運(yùn)行。在網(wǎng)上下載社區(qū)模塊時(shí),請(qǐng)注意是否支持你所使用的 Odoo 版本。
大版本發(fā)布(如15.0)通常會(huì)有比較頻繁的升級(jí),這大部分都是漏洞修復(fù)而非新功能的開(kāi)發(fā)。這些升級(jí)確保 API 穩(wěn)定,即模型數(shù)據(jù)結(jié)構(gòu)和視圖元素標(biāo)識(shí)符保持穩(wěn)定。這很重要,因?yàn)檫@樣就不會(huì)因?yàn)樯嫌蝺?nèi)核模塊做出不兼容修改而導(dǎo)致自定義模塊崩潰。
Odoo 在線 SaaS 版本可能會(huì)使用中間版,有時(shí)也稱(chēng)為 SaaS 版。它們也是官方支持的。當(dāng)前支持的版本列表可見(jiàn)于https://www.odoo.com/documentation/user,在 Support 頁(yè)面的 Practical Information 中。
master 分支的版本會(huì)形成下一個(gè)大版本的更新,但在發(fā)布前其 API 并不穩(wěn)定,不應(yīng)使用它構(gòu)建自定義模塊。那會(huì)好比在流沙中前行,無(wú)法知道何時(shí)會(huì)出現(xiàn)導(dǎo)致自定義模塊崩潰的修改。請(qǐng)收下這個(gè)警告。
Odoo 的架構(gòu)
了解Odoo 遵循多層架構(gòu)以及我們使用的每種組件的角色會(huì)很有幫助。因此我們來(lái)學(xué)習(xí)下 Odoo 應(yīng)用的架構(gòu)并通過(guò)將其解構(gòu)為多個(gè)組件層來(lái)幫助我們進(jìn)行應(yīng)用的開(kāi)發(fā)。
Odoo 應(yīng)用可以解構(gòu)為三層:數(shù)據(jù)層、邏輯層和展示層:

圖1.1:Odoo 應(yīng)用分層
數(shù)據(jù)層是最底端一層,負(fù)責(zé)數(shù)據(jù)存儲(chǔ)和持久化,Odoo 借助 PostgreSQL服務(wù)端來(lái)實(shí)現(xiàn)。Odoo 出于設(shè)計(jì)考慮僅支持 PostgreSQL 數(shù)據(jù)庫(kù)。文檔附件、圖片一類(lèi)的二進(jìn)制文件通常存儲(chǔ)在一個(gè)稱(chēng)為 filestore(目錄) 的文件系統(tǒng)中。
小貼士:?也就是說(shuō) Odoo 實(shí)例的完整備份需包含數(shù)據(jù)庫(kù)導(dǎo)出文件和 filestore 的拷貝。
我們很少使用 SQL 直接與數(shù)據(jù)庫(kù)引擎進(jìn)行交互 ,但在特定場(chǎng)景可能會(huì)需要用到。
Odoo 依賴(lài)于對(duì)象關(guān)系映射(ORM)作為應(yīng)用和數(shù)據(jù)庫(kù)之間的接口。ORM 提供插件模塊與數(shù)據(jù)交互的應(yīng)用程序接口(API)。我們使用ORM模型實(shí)現(xiàn)數(shù)據(jù)層。例如,用于客戶(hù)或供應(yīng)商數(shù)據(jù)的Partner數(shù)據(jù)實(shí)體,以模型進(jìn)行表示。
通常底層數(shù)據(jù)庫(kù)應(yīng)僅由這一層訪問(wèn),因?yàn)樗_保了安全權(quán)限控制和數(shù)據(jù)一致性。ORM 模型基于支持多個(gè)交互方法的Python對(duì)象類(lèi),如增刪改查(CRUD)基本操作。具體來(lái)說(shuō)CRUD操作通過(guò)create()?、search()?、write()?和unlink()?模型方法實(shí)現(xiàn)。
邏輯層負(fù)責(zé)與數(shù)據(jù)層的所有交互,并由 Odoo 服務(wù)端處理??蓴U(kuò)展CRUD操作來(lái)實(shí)現(xiàn)具體的業(yè)務(wù)邏輯。例如,create()?和?write()?方法可實(shí)現(xiàn)默認(rèn)值或其它的自動(dòng)操作。可添加其它方法來(lái)強(qiáng)制驗(yàn)證規(guī)則或自動(dòng)計(jì)算字段值。
展示層用于展示數(shù)據(jù)并與用戶(hù)交互,通過(guò)軟件的客戶(hù)端實(shí)現(xiàn),負(fù)責(zé)用戶(hù)交互??蛻?hù)端軟件使用遠(yuǎn)程過(guò)程調(diào)用(RPC)運(yùn)行 ORM 引擎及業(yè)務(wù)邏輯的Odoo 服務(wù)。ORM API調(diào)用發(fā)往Odoo服務(wù)端處理讀、寫(xiě)、驗(yàn)證或執(zhí)行其它操作。然后將結(jié)果返回客戶(hù)端做進(jìn)一步處理。
Odoo自帶一個(gè)網(wǎng)頁(yè)客戶(hù)端。網(wǎng)頁(yè)客戶(hù)端支持所有業(yè)務(wù)應(yīng)用所需的功能,如登錄會(huì)話(huà)、導(dǎo)航菜單、數(shù)據(jù)列表和表單。
有一個(gè)網(wǎng)站框架用于外部的開(kāi)發(fā)前臺(tái)。它提供一些 CMS 功能,可用于創(chuàng)建靜態(tài)和動(dòng)態(tài)網(wǎng)頁(yè)。網(wǎng)站框架使用controller組件來(lái)實(shí)現(xiàn)具體展示邏輯的代碼,與模型內(nèi)部邏輯分離。頁(yè)面使用QWeb作為其渲染引擎。那是一些包含HTML標(biāo)記外加循環(huán)、條件或調(diào)用其它模板的特有XML QWeb標(biāo)簽。
Odoo 服務(wù)端 API 非常開(kāi)放,包含所有的服務(wù)端功能。官方Web 客戶(hù)端使用的 API 與其它應(yīng)用的 API 并無(wú)不同。因此,其它的客戶(hù)端實(shí)現(xiàn)均可做到,并且可以在任何平臺(tái)上使用任意編程語(yǔ)言進(jìn)行實(shí)現(xiàn)??梢詣?chuàng)建桌面和移動(dòng)端應(yīng)用來(lái)提供不同用戶(hù)界面,這充分利用了 Odoo 為業(yè)務(wù)邏輯和數(shù)據(jù)持久性而生的數(shù)據(jù)和邏輯層。
使用 Odoo SaaS試用數(shù)據(jù)庫(kù)
使用Odoo最簡(jiǎn)單的方式是使用Odoo的軟件即服務(wù)(SaaS)試用數(shù)據(jù)庫(kù)。這樣無(wú)需進(jìn)行任何安裝,僅需進(jìn)入官網(wǎng)https://odoo.com/點(diǎn)擊Try it free按鈕。
會(huì)要求選擇一個(gè)應(yīng)用來(lái)在新數(shù)據(jù)庫(kù)中進(jìn)行安裝。在本章的學(xué)習(xí)中,你可以選擇任何應(yīng)用,讀者大可自由選擇。如果你實(shí)在拿不定主意,不妨使用CRM應(yīng)用。

圖1.2 – Odoo SaaS試用數(shù)據(jù)庫(kù)的初始應(yīng)用選取
新的SaaS數(shù)據(jù)庫(kù)使用最新的Odoo SaaS版本,它是基于最近的穩(wěn)定版Odoo EE,同時(shí)帶有自己的小版本號(hào)。因此與Odoo最新穩(wěn)定的企業(yè)版版本號(hào)并不致。
免費(fèi)數(shù)據(jù)庫(kù)有效期為15天。在寫(xiě)本書(shū)時(shí),Odoo SaaS版本還提供一個(gè)免費(fèi)方案讓你可以在到期后繼續(xù)使用(要求安裝一個(gè)以上的應(yīng)用)。
在工作站上安裝 Odoo
使用Odoo SaaS測(cè)試庫(kù)是本章的默認(rèn)選項(xiàng)。在本書(shū)之后的章節(jié)中,我們會(huì)使用本地Odoo安裝。在第二章 Odoo 15開(kāi)發(fā)之開(kāi)發(fā)環(huán)境準(zhǔn)備中,會(huì)進(jìn)行相應(yīng)的引導(dǎo)。
值得一提的是Odoo還有一些預(yù)打包的安裝包。我們這里簡(jiǎn)要地進(jìn)行說(shuō)明,以供讀者了解:
在你的操作系統(tǒng)上使用預(yù)打包安裝程序安裝Odoo:如果是Odoo新手又希望快速獲得一個(gè)本地環(huán)境的話(huà)這是一個(gè)很好的選擇。預(yù)打包安裝軟件支持如下操作系統(tǒng):Windows?(EXE安裝軟件);?Debian/Ubuntu?(DEB包)和CentOS/RHEL?(RPM包)。
使用 Docker 容器安裝 Odoo:如果用過(guò) Docker 并在操作系統(tǒng)中安裝了 Docker 這會(huì)是一個(gè)好選項(xiàng)。如果不太了解 Docker,可以采用上一種方法,以名學(xué)習(xí) Docker影響到正課(學(xué)習(xí) Odoo 開(kāi)發(fā))。
可通過(guò)https://download.odoo.com下載這些安裝包。包含所有穩(wěn)定版的Odoo,以及與最新開(kāi)發(fā)版本相對(duì)應(yīng)的 master 分支。我們會(huì)在下面的小節(jié)講解這些選項(xiàng)。
有關(guān)安裝Odoo的更多知識(shí),請(qǐng)參見(jiàn)官方文檔。
使用一鍵安裝包在 Windows 上安裝
Odoo為Windows提供了一個(gè)一鍵安裝包,包含運(yùn)行Odoo所需的所有:Python 3運(yùn)行時(shí)環(huán)境、PostgreSQL數(shù)據(jù)庫(kù)以及安裝了依賴(lài)的Odoo服務(wù)端。
可通過(guò)https://download.odoo.com下載安裝包。在首頁(yè)選擇相應(yīng)的版本:15 (stable) - Community Edition。每日構(gòu)建包位于15.0/nightly/windows,最新包在頁(yè)面底部。
安裝包非常易于使用。在安裝結(jié)束時(shí)Odoo會(huì)自動(dòng)啟動(dòng)。
還會(huì)創(chuàng)建開(kāi)機(jī)啟動(dòng)的Windows服務(wù)用于自動(dòng)啟動(dòng)Odoo和PostgreSQL。在通過(guò)其它如源碼方式安裝時(shí)應(yīng)注意這一點(diǎn),在Windows安裝包安裝后會(huì)占用8069端口,這樣其它安裝就無(wú)法使用該端口了。
使用預(yù)打包安裝包在 Linux 上安裝
Odoo下載站點(diǎn)(https://download.odoo.com) 還提供對(duì)Debian系(含Ubuntu)和RHEL/CentOS的官方包下載倉(cāng)庫(kù)。
在首頁(yè)上對(duì)于有對(duì)應(yīng)系統(tǒng)安裝包(apt?或?yum) 的安裝指南。請(qǐng)確保將命令行示例中的Odoo版本修改為對(duì)應(yīng)的版本,如15.0。
# Debian 系
wget -O - https://nightly.odoo.com/odoo.key | apt-key add -
echo "deb http://nightly.odoo.com/15.0/nightly/deb/ ./" >> /etc/apt/sources.list
apt-get update && apt-get install odoo
# RHEL/CentOS
yum-config-manager --add-repo=https://nightly.odoo.com/15.0/nightly/rpm/odoo.repo
yum update && yum install odoo
在Linux系統(tǒng)中安裝Odoo 15之前,應(yīng)當(dāng)先安裝好PostgreSQL數(shù)據(jù)庫(kù)。這樣Odoo就可以創(chuàng)建并配置其用戶(hù)了。
使用 Docker 容器安裝 Odoo
Docker為在運(yùn)行應(yīng)用提供了一個(gè)便利的多平臺(tái)解決方案??捎糜谠赪indows、Linux和macOS上運(yùn)行應(yīng)用。相比于傳統(tǒng)的虛擬機(jī)容器技術(shù)使用簡(jiǎn)單、資源利用率高。
首先需要在操作系統(tǒng)中安裝Docker。Docker Desktop是社區(qū)版的,免費(fèi)使用??赏ㄟ^(guò)https://www.docker.com進(jìn)行下載。安裝最新版本 Docker時(shí)最好參照該網(wǎng)站。Docker依賴(lài)于虛擬硬件技術(shù),請(qǐng)確保在基本輸出輸出系統(tǒng)?(BIOS)中啟用該功能。
有關(guān)安裝和運(yùn)行Docker的通用指南請(qǐng)見(jiàn)https://docs.docker.com/engine/install。
例如對(duì)于Ubuntu系統(tǒng),詳細(xì)地的安裝說(shuō)明位于https://docs.docker.com/engine/install/ubuntu/。
關(guān)于安裝后的重要步驟,如以非root用戶(hù)運(yùn)行Docker,請(qǐng)參見(jiàn)https://docs.docker.com/engine/install/linux-postinstall/。
Windows系統(tǒng)中的Docker桌面需要使用Hyper-V,僅在Windows?10的企業(yè)版和教育版中才有。最新安裝詳情請(qǐng)見(jiàn)https://docs.docker.com/desktop/windows/install/。
Mac上的Docker桌面需要使用macOS 10.14或更新版本。最新的詳情請(qǐng)見(jiàn)https://docs.docker.com/desktop/mac/install/。
注:?在Windows和macOS版本中曾經(jīng)可使用Docker Toolbox作為替代,但這一發(fā)行版已被廢棄。Docker Toolbox打包了VirtualBox,提供了預(yù)配置的shell用于在命令行操作Docker容器。參見(jiàn)https://docs.docker.com/toolbox/獲取更多詳情。
Odoo 在Docker Hub上的官方Docker鏡像位于https://hub.docker.com/_/odoo。這里我們可以看到使用Odoo Docker鏡像的基本指南。運(yùn)行Odoo時(shí)會(huì)創(chuàng)建兩個(gè)Docker容器:一個(gè)用于PostgreSQL數(shù)據(jù)庫(kù),另一個(gè)用于Odoo服務(wù)端。
安裝及操作均通過(guò)命令行實(shí)現(xiàn)。通過(guò)如下命令啟動(dòng)PostgreSQL的Docker容器:
$ docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:13
這樣會(huì)通過(guò)互聯(lián)網(wǎng)下載最新的PostgreSQL鏡像并啟動(dòng)一個(gè)以后臺(tái)任務(wù)運(yùn)行的容器。
接著,安裝、運(yùn)行Odoo服務(wù)端容器,聯(lián)結(jié)剛剛啟動(dòng)的PostgreSQL容器,對(duì)外暴露端口8069:
$ docker run -t -p 8069:8069 --name odoo --link db:db odoo:15.0 -d odoo15
此時(shí)便可在終端窗口看到實(shí)時(shí)的 Odoo 服務(wù)器日志,在瀏覽器中訪問(wèn)http://localhost:8069即可打開(kāi)?Odoo 實(shí)例。
注:?如果8069端口被占用了,則Odoo 服務(wù)啟動(dòng)會(huì)失敗。比如端口可能被正在運(yùn)行的 Odoo 服務(wù)端所占用。此時(shí)我們需要查找停止占用該端口的服務(wù)(比如查找運(yùn)行中的服務(wù)列表)或者使用-p 參數(shù)指定其它端口來(lái)運(yùn)行 Odoo。如修改為8070端口(-p 8070:8069)。還可通過(guò)-d <dbname>?
參數(shù)修改實(shí)例所需使用的數(shù)據(jù)庫(kù)名稱(chēng)。
以下Docker 的幾個(gè)基本命令會(huì)有助于管理容器:
docker stop <name>
:停止容器docker start <name>
:?jiǎn)?dòng)容器docker start -a <name>
:?jiǎn)?dòng)容器并附帶輸出,如在命令終端中輸出的服務(wù)器日志docker attach <name>
:重新添加容器輸出至當(dāng)前終端窗口docker ps
:列出當(dāng)前 Docker 容器
以上就是操作 Docker 容器的基本命令。
萬(wàn)一在運(yùn)行容器時(shí)出現(xiàn)問(wèn)題,可以執(zhí)行如下命令重新來(lái)過(guò):
$ docker container stop db
$ docker container rm db
$ docker container stop odoo
$ docker container rm odoo
Docker 技術(shù)的應(yīng)用非常廣泛,學(xué)習(xí)起來(lái)也很有趣。Docker官網(wǎng)上有不錯(cuò)的文檔可供學(xué)習(xí),可先通過(guò)https://www.docker.com/get-started開(kāi)始學(xué)習(xí)。
啟用開(kāi)發(fā)者工具
要實(shí)現(xiàn)我們的項(xiàng)目,這里需要用到Odoo開(kāi)發(fā)者工具。通過(guò)開(kāi)啟開(kāi)發(fā)者模式即可使用這些工具。
開(kāi)發(fā)者模式對(duì)于查看和修改當(dāng)前Odoo的配置很有用??芍苯油ㄟ^(guò)用戶(hù)界面自定義Odoo應(yīng)用并快速添加、修改功能??捎盟鲂┬⌒薷?,比如創(chuàng)建帶有自己菜單、視圖及底層數(shù)據(jù)模型的應(yīng)用。
注意:開(kāi)發(fā)者暴露了Odoo應(yīng)用的大量?jī)?nèi)部配置,可對(duì)其進(jìn)行修改。但能力越大,責(zé)任真大,所以應(yīng)謹(jǐn)慎修改。在線上系統(tǒng)中請(qǐng)保持在拷貝數(shù)據(jù)庫(kù)中進(jìn)行這些修改。如果出現(xiàn)問(wèn)題,還有機(jī)會(huì)通過(guò)升級(jí)所影響的應(yīng)用(或是base模塊)在解決問(wèn)題,但不是100%保證。
這種通過(guò)開(kāi)發(fā)者工具的自定義開(kāi)發(fā)相對(duì)于在后續(xù)章節(jié)講到的編程工具而言存在其局限性。如它無(wú)法添加或擴(kuò)展默認(rèn)的 ORM 方法。
借助于開(kāi)者模式(通過(guò)Odoo Studio應(yīng)用)的自定義開(kāi)發(fā)不易于集成到結(jié)構(gòu)性開(kāi)發(fā)流,如版本控制、自動(dòng)化測(cè)試及質(zhì)量測(cè)試、預(yù)發(fā)布和生產(chǎn)環(huán)境改進(jìn)的工作流。
本文我們主要使用開(kāi)發(fā)者模式來(lái)介紹在 Odoo 框架中應(yīng)用配置數(shù)據(jù)是如何進(jìn)行組織的,以及如何在開(kāi)發(fā)者模式下完成簡(jiǎn)單的自定義或原型解決方案。
開(kāi)啟開(kāi)發(fā)者模式
從Odoo 13開(kāi)始,通過(guò)Settings?>?General Settings頁(yè)面開(kāi)啟開(kāi)發(fā)者模式。在接近底部的地方會(huì)發(fā)現(xiàn)一個(gè)Developer Tools的版塊。在這里可以找到Activate the developer mode鏈接。點(diǎn)擊該鏈接就會(huì)在當(dāng)前瀏覽器窗口中開(kāi)啟開(kāi)發(fā)者模式功能:

圖1.3 – Settings頁(yè)面中的開(kāi)發(fā)者工具選項(xiàng)
注意需要至少安裝了一個(gè)應(yīng)用后才會(huì)出現(xiàn)General Settings菜單。如果找不到該菜單,請(qǐng)安裝一個(gè)應(yīng)用,如Contacts或CRM等任一應(yīng)用。
Odoo 13中的變化:Odoo 10到12版本,開(kāi)發(fā)者模式都是通過(guò)Settings?>?Dashboard頁(yè)面右下角處開(kāi)啟。而對(duì)于Odoo 9及之前的版本,開(kāi)發(fā)者模式是在網(wǎng)頁(yè)右上角中的User菜單的About對(duì)話(huà)窗口中激活,
啟用了開(kāi)發(fā)者模式后,會(huì)出現(xiàn)如下的菜單:
菜單欄中,右上角聊天和活動(dòng)圖標(biāo)左側(cè)會(huì)新增一個(gè)開(kāi)發(fā)者工具的小蟲(chóng)子圖標(biāo)。
在Settings應(yīng)用中,頂欄中會(huì)出現(xiàn)Technical和Translations菜單項(xiàng)。

圖1.4 – 開(kāi)啟了開(kāi)發(fā)者模式后的設(shè)置頁(yè)面
開(kāi)啟開(kāi)發(fā)者模式后在網(wǎng)頁(yè)視圖上會(huì)出現(xiàn)一些額外信息,即在將鼠標(biāo)懸停在字段上,會(huì)有一個(gè)提示框顯示相關(guān)的技術(shù)信息。
注:?我們也可以通過(guò)修改當(dāng)前的 URL 來(lái)進(jìn)入開(kāi)發(fā)者模式,這樣就無(wú)需進(jìn)入 Settings 頁(yè)面。僅需修改鏈接中的.../web#...為.../web?debug=1#...。比如修改http:///localhost:8069/web#home為http://localhost_8069/web?debug#home。
使用帶資源的開(kāi)發(fā)者模式
為了加載更快,網(wǎng)頁(yè)客戶(hù)端對(duì)JavaScript和CSS資源進(jìn)行了最小化壓縮。這會(huì)給調(diào)試帶來(lái)困難。
Activate the developer mode (with assets)?選項(xiàng)會(huì)阻止這種最小化壓縮,讓每個(gè)資源單獨(dú)加載。對(duì)于在網(wǎng)頁(yè)客戶(hù)端中進(jìn)行調(diào)試這很有用處,但也會(huì)因開(kāi)銷(xiāo)開(kāi)讓頁(yè)面的瀏覽變慢。
小貼士:Firefox和Chrome瀏覽器都有插件可提供一個(gè)按鈕,方便開(kāi)啟及禁用Odoo中的開(kāi)發(fā)者模式。請(qǐng)?jiān)诓寮痰曛兴阉鱋doo Debug。
說(shuō)說(shuō) Odoo Studio
值得一提的是Odoo企業(yè)版和SaaS版都提供了Odoo Studio應(yīng)用,這是一個(gè)交互的應(yīng)用構(gòu)造器。我們不會(huì)使用到它,因?yàn)楸緯?shū)的示例均使用 Odoo 社區(qū)版,社區(qū)版中沒(méi)有這一功能。
Odoo Studio提供了一套用戶(hù)友好的界面,用于完成本章中講解的交互式開(kāi)發(fā)功能及一些其它功能,比如可以將自定義功能導(dǎo)出到文件中。
這里我們會(huì)使用開(kāi)發(fā)者模式(有時(shí)也被稱(chēng)為debug模型)及Technical菜單,這兩者在Odoo所有的版本中都可用。Odoo Studio中所構(gòu)建的大部分功能通過(guò)這兩個(gè)工具也可完成,不過(guò)對(duì)于非開(kāi)發(fā)者來(lái)說(shuō)確實(shí)也難些。
對(duì)模型添加自定義字段
向已有表單添加自定義字段是一種很覺(jué)的自定義,無(wú)需創(chuàng)建自定義模塊通過(guò)用戶(hù)界面就可實(shí)現(xiàn)。
我們的to-do清單應(yīng)用中,希望選擇一組人共同操作to-do清單項(xiàng)??梢栽谒麄兊膒artner表單設(shè)置一個(gè)標(biāo)記來(lái)進(jìn)行指定。我們將通過(guò)向Contact模型添加一個(gè)Is Work Team??標(biāo)記來(lái)實(shí)現(xiàn)。
Contact模型是Odoo內(nèi)核自帶的,即使未安裝任何應(yīng)用也可以使用。但這樣就沒(méi)有菜單選項(xiàng)來(lái)訪問(wèn)它了。
如果在主菜單中沒(méi)有Contacts應(yīng)用的話(huà),請(qǐng)進(jìn)行安裝。打開(kāi)頂級(jí)菜單的Apps項(xiàng),搜索該應(yīng)用進(jìn)行安裝。

圖1.5 – Apps菜單中添加Contacts應(yīng)用
安裝完成后即可在頂級(jí)菜單中找到 Contacts 項(xiàng)。
對(duì)模型添加字段
我們先在數(shù)據(jù)模型中添加自定義字段。
點(diǎn)擊Contacts應(yīng)用菜單項(xiàng)查看聯(lián)系人主視圖。點(diǎn)擊開(kāi)發(fā)者工具小蟲(chóng)圖標(biāo)并選擇View Fields選項(xiàng)。
ODOO 12中的變化
開(kāi)發(fā)者菜單中的View Fields選項(xiàng)是在Odoo 12中新增的,可通過(guò)Settings?>Technical?>Database Structure菜單添加、編輯字段??梢允褂肕odels或Fields選項(xiàng)。
此時(shí)會(huì)看到當(dāng)前模型Contact所有已有字段的列表。點(diǎn)擊左上角的Create按鈕、填入新字段的以下詳情:
Field Name:?x_is_work_team
Field Label:?Is Work Team?
Field Type:?boolean

圖1.6 – 創(chuàng)建Is Work Team?字段
字段名(Field Name)必須以 x_開(kāi)頭。這是通過(guò)開(kāi)發(fā)者工具創(chuàng)建模型和字段強(qiáng)制要求的(否則保存時(shí)會(huì)提示Custom fields must have a name that starts with 'x_' !)。通過(guò)插件模塊的自定義開(kāi)發(fā)沒(méi)有這一限制。
點(diǎn)擊Save,就會(huì)在字段列表中新增這個(gè)字段。默認(rèn),列表視圖顯示80條記錄,因此需要點(diǎn)擊右上角的右鍵瀏覽下一頁(yè)查看新字段,或者也可以編輯箭頭旁的記錄數(shù)。
對(duì)表單視圖添加字段
現(xiàn)在Contact模型中就有一個(gè)新字段(前面也提到過(guò)也稱(chēng)為Partner模型)。但在用戶(hù)界面中仍不可見(jiàn)。需要為其給定一個(gè)視圖。我們會(huì)添加一個(gè)聯(lián)系人表單視圖。
回到Contacts的列表并打開(kāi)表單視圖,可通過(guò)選擇已有的聯(lián)系人或點(diǎn)擊Create按鈕。
現(xiàn)在需要決定在表單的哪里添加這個(gè)字段。例如,我們應(yīng)在Tags標(biāo)簽后進(jìn)行添加。這會(huì)是使用的擴(kuò)展點(diǎn)。
將鼠標(biāo)懸浮在字段上,會(huì)顯示其技術(shù)信息,如下圖所示:

圖1.7 – 帶有技術(shù)詳情提示信息的Tags字段
接下,我們需要找到該字段的技術(shù)名稱(chēng)。可通過(guò)將鼠標(biāo)懸停在字段標(biāo)簽之上。這樣我們可以看到該字段的名稱(chēng)為category_id。
現(xiàn)在可以擴(kuò)展表單視圖添加字段。點(diǎn)擊開(kāi)發(fā)者工具小蟲(chóng)圖標(biāo),選取Edit View: Form選項(xiàng)。這會(huì)打開(kāi)表單定義的容器。

圖1.8 – 表單視圖編輯窗口
在Architecture標(biāo)簽頁(yè)下,可以看到基礎(chǔ)視圖的XML。可以直接進(jìn)行編輯,但這不是個(gè)好做法,因?yàn)樵谀K升級(jí)時(shí)修改會(huì)丟失。正確的方式是通過(guò)創(chuàng)建一個(gè)擴(kuò)展視圖來(lái)對(duì)其編輯。
安裝額外的模型可以對(duì)基礎(chǔ)視圖添加更多的字段及視覺(jué)元素。這是通過(guò)使用擴(kuò)展視圖完成的,并且可在Inherited Views標(biāo)簽頁(yè)下查看。我們會(huì)在這里為聯(lián)系人表單視圖添加我們的擴(kuò)展。
在Inherited Views列表中,點(diǎn)擊底部的Add a line?,使用如下的值創(chuàng)建擴(kuò)展視圖:
View Name:?添加一些短描述,如Contacts Form extensions for To-do App。
Architecture:?這會(huì)要求一個(gè)指定擴(kuò)展點(diǎn)及所添加內(nèi)容的XML片斷。使用
?<field name="category_id" position="after"><field name="x_is_work_team"/></field>?
。
擴(kuò)展視圖應(yīng)當(dāng)像下圖這樣:

圖1.9 – 創(chuàng)建擴(kuò)展視圖來(lái)添加x_is_work_team
字段
現(xiàn)在點(diǎn)擊Save & Close,如果所填XML沒(méi)有錯(cuò)誤,會(huì)加到Inherited Views列表,其中會(huì)包含我們添加的擴(kuò)展。點(diǎn)擊Save按鈕完成對(duì)表單視圖的修改,通過(guò)點(diǎn)擊右上角的x關(guān)閉Edit Form: View窗口。
修改已完成,但需要重新加載表單才能看到修改。重新加載頁(yè)面,現(xiàn)在Tags字段下面應(yīng)該會(huì)出Is Work Team??字段,如下圖所示:

圖1.10 – 帶有Is Work Team? 字段的聯(lián)系人表單視圖
這樣就完成了在表單視圖中添加自定義字段的步驟。表單只是這些視圖類(lèi)型中的一種。下一節(jié)中詳細(xì)討論視圖的類(lèi)型。
了解視圖類(lèi)型
我們剛剛操作了一種視圖類(lèi)型,表單視圖。但用戶(hù)界面中還使用了其它的視圖類(lèi)型。
Contacts的初始視圖類(lèi)型為看板視圖,以數(shù)據(jù)卡片顯示一些字段。看視圖還可以按列組織卡片。例如,CRM應(yīng)用以這種初始視圖形式顯示,稱(chēng)為管道視圖。在看板視圖中,開(kāi)發(fā)者菜單中顯示Edit View: Kanban選項(xiàng)。
列表視圖(有時(shí)也稱(chēng)為樹(shù)狀視圖)以列表顯示記錄。在列表視圖中,開(kāi)發(fā)者菜單會(huì)顯示Edit View: List選項(xiàng)。
最后,搜索視圖控制看板視圖及列表視圖右上角搜索框的行為,以及其下的按鈕:Filters和Group By。在搜索框可見(jiàn)時(shí),開(kāi)發(fā)者菜單會(huì)顯示一個(gè)Edit View: ControlPanelView選項(xiàng)。
視圖類(lèi)型并不僅限于這些,還有其它的類(lèi)型,我們會(huì)在第十章 Odoo 15開(kāi)發(fā)之后臺(tái)視圖 - 設(shè)計(jì)用戶(hù)界面中進(jìn)行探討。
可通過(guò)Settings?>?Technical?>?User Interface?>?Views菜單項(xiàng)查看所有的視圖定義。
一種更詳細(xì)的方式是使用Settings?>?Technical?>?Database Structure?>?Models來(lái)所要的模型(本例為res.partner,也稱(chēng)之為Contact),并打開(kāi)Views標(biāo)簽。

圖1.11 – Contact模型的數(shù)據(jù)庫(kù)結(jié)構(gòu)
這里,我們可以看到所選模型的所有視圖定義。可以通過(guò)View Type列看到不同類(lèi)型視圖的記錄,以及基礎(chǔ)視圖及它們的擴(kuò)展。修改或新增視圖記錄會(huì)即刻生效,在下次重新加載視圖時(shí)即可看到修改。
按視圖類(lèi)型排序有助于查看同一視圖類(lèi)型的所有擴(kuò)展。
基礎(chǔ)視圖是Inherited View字段,有些為空。視圖類(lèi)型并不僅限于一種基礎(chǔ)視圖。例如,Contact模型(res.partner)的表單視圖有多個(gè)基礎(chǔ)視圖,如base.view_partner_form和base.view_partner_simple_form。
視圖還有一個(gè)Sequence字段。Sequence序號(hào)最小的基礎(chǔ)視圖為默認(rèn)顯示的視圖。在查看表單視圖定義時(shí),會(huì)看到這個(gè)Sequence值。窗口動(dòng)作用于菜單項(xiàng),可指定具體使用的基礎(chǔ)視圖。我們提到,如果未定義某個(gè)視圖,會(huì)使用序號(hào)最小的那個(gè)。
新建模型
模型是構(gòu)建應(yīng)用的基本組件,包含了所需使用到的數(shù)據(jù)結(jié)構(gòu)和存儲(chǔ)。接下來(lái)我們就為 To-do 清單應(yīng)用添加模型,有三個(gè)字段:
Description文本
Is done? 標(biāo)記
Work team(即在清單中相互協(xié)作的用戶(hù)列表)
模型名應(yīng)使用單數(shù)形式,因此新模型的名稱(chēng)應(yīng)為T(mén)o-do Item。模型技術(shù)名稱(chēng)必須為有效的數(shù)據(jù)庫(kù)對(duì)象標(biāo)識(shí)符,因此我們應(yīng)使用字母和下劃線,避免使用其它符號(hào)。因?yàn)橥ㄟ^(guò)Technical菜單創(chuàng)建的模型必須帶有x_?前綴,這個(gè)新模型的技術(shù)名稱(chēng)使用x_todo_item。
通過(guò)菜單Settings > Technical > Database Structure > Models進(jìn)入模型定義頁(yè)面。
點(diǎn)擊Models列表中的Create按鈕創(chuàng)建新模型:
填入基本定義值:在Model Description字段中輸入To-do Item,Model字段輸入x_todo_item。
默認(rèn),模型會(huì)在字段列表中包含x_name字段。這是在列表中顯示記錄或在其它記錄引用它時(shí)顯示的標(biāo)題??捎米鱐o-do Item的標(biāo)題,因此編輯修改相應(yīng)的Field Label列(改為 Title)。
接下來(lái)添加Is Done??字段。這應(yīng)當(dāng)很明確。在Fields列表中,點(diǎn)擊底部的Add a line打開(kāi)新的視圖表單,輸入如下值:
然后點(diǎn)擊Save & Close按鈕,再點(diǎn)擊模型表單中的Save。

圖1.12 – 新建字段表單Field Name:?x_is_done
Field Label:?Is Done?
Field Type:?boolean
接下來(lái)的Work Team字段應(yīng)該會(huì)更有挑戰(zhàn)性了。不僅是因?yàn)檫@是一個(gè)引用Contact?(res.partner)模型中記錄的關(guān)聯(lián)字段,而且它還是一個(gè)多值選擇字段。
所幸的是Odoo支持多對(duì)多關(guān)聯(lián)。本例正是如此,因?yàn)槊織l任務(wù)清單可關(guān)聯(lián)多個(gè)聯(lián)系人,而每個(gè)聯(lián)系人又可關(guān)聯(lián)多條任務(wù)清單。
在Fields列表中添加Work Team字段,需要再次點(diǎn)擊表單的Edit按鈕,接著點(diǎn)擊Add a line打開(kāi)新增字段表單。然后輸入如下值:多對(duì)多字段有一些專(zhuān)有的基礎(chǔ)屬性:Relation Table,?Column 1和Column 2。這些會(huì)自動(dòng)進(jìn)行填寫(xiě),通常使用默認(rèn)值即可。在第六章 Odoo 15開(kāi)發(fā)之模型 - 結(jié)構(gòu)化應(yīng)用數(shù)據(jù)中會(huì)詳細(xì)討論到這些屬性。
Domain屬性是可選的,它為所展示的記錄定義了一個(gè)過(guò)濾器。我們使用它來(lái)將聯(lián)系人限定為勾選了Is Work Team??標(biāo)記的人。否則會(huì)在選項(xiàng)中出現(xiàn)所有聯(lián)系人。Domain 表達(dá)式遵循Odoo 獨(dú)有的語(yǔ)法 - 一個(gè)包含三個(gè)值的可迭代對(duì)象,每個(gè)對(duì)象是一個(gè)過(guò)濾條件,表示待過(guò)濾的字段名、過(guò)濾運(yùn)算符及過(guò)濾所使用的值。詳細(xì)的解釋參見(jiàn)第七章 Odoo 15開(kāi)發(fā)之記錄集 - 使用模型數(shù)據(jù)。
小貼士:?Odoo有一個(gè)交互式的 domain 過(guò)濾向?qū)Э蓭椭勺饔糜虮磉_(dá)式。訪問(wèn)Settings > Technical > User Interface > User-defined Filters菜單。在表單中選中目標(biāo)模型后,Domain字段會(huì)顯示一個(gè)?+ Add filter按鈕用于添加過(guò)濾條件。下面的文本框會(huì)動(dòng)態(tài)地顯示作用域表達(dá)式代碼。
Field Name:?x_work_team_ids
Field Label:?Work Team
Field Type:?many2many
Related Model:?res.partner
Domain:?[('x_is_work_team', '=', True)]
在完成后,點(diǎn)擊模型表單的Save。創(chuàng)建好新模型后,會(huì)自動(dòng)添加一些字段。ORM引擎在所有模型中添加了它們,在進(jìn)行審計(jì)時(shí)會(huì)很有幫助:

圖1.13 – To-do清單模型的數(shù)據(jù)庫(kù)結(jié)構(gòu)
現(xiàn)在to-do列表應(yīng)用的底層模型就緒了,但用戶(hù)還是無(wú)法訪問(wèn)。為此,需要配置訪問(wèn)權(quán)限。在下一節(jié)中我們進(jìn)行學(xué)習(xí)。
創(chuàng)建菜單項(xiàng)和動(dòng)作
現(xiàn)在已經(jīng)有了存儲(chǔ)任務(wù)清單的模型,我們希望在用戶(hù)界面中添加它??稍赨I中添加菜單項(xiàng)實(shí)現(xiàn)。
我們會(huì)創(chuàng)建一個(gè)直接打開(kāi)任務(wù)列表的頂級(jí)菜單。一些應(yīng)用(如Contacts)正是這樣,而另一些則是頂欄下的子菜單。
菜單的定義位于Settings應(yīng)用的Technical?>?User Interface?>?Menu Items?中:

圖1.14 – Technical菜單中的Menu Items選項(xiàng)
我們執(zhí)行如下步驟創(chuàng)建菜單項(xiàng):
進(jìn)行上圖的頁(yè)面,點(diǎn)擊Create,輸入如下值:
Menu: To-do
Parent Menu: 留空
Action: 選擇?ir.actions.act_window
在Action字段旁的選擇框中輸入To-do Items, 在下拉列表中選擇Create and Edit...?,這時(shí)會(huì)打開(kāi)Create: Action?表單彈窗。
在Create: Action表單中,設(shè)置如下值:

圖1.15 – Create: Action表單
Action Name:?To-do Items
External ID Object: x_todo_item (目標(biāo)模型的技術(shù)名稱(chēng))。
此時(shí),動(dòng)作定義應(yīng)該是下面這樣:
點(diǎn)擊Create: Action?表單中的Save。然后在Menu Items表單中點(diǎn)擊Save,然后to-do列表應(yīng)用的菜單項(xiàng)就差不多可以使用了。
菜單的修改要求對(duì)整個(gè)頁(yè)面重新加載才可以看到。大多數(shù)瀏覽器可通過(guò)F5快捷鍵來(lái)重新加載。但如果現(xiàn)在刷新頁(yè)面的話(huà),是看不到To-do菜單的。為什么呢?我們現(xiàn)在還看不到菜單的原因是還沒(méi)有給用戶(hù)授權(quán)訪問(wèn)。
在對(duì)用戶(hù)展示菜單項(xiàng)之前需要配置訪問(wèn)權(quán)限。我們?cè)诒菊轮袝?huì)進(jìn)行處理,但在那之前,有必要更深入地討論一下窗口動(dòng)作。
了解窗口動(dòng)作
本例中,對(duì)不帶有子菜單項(xiàng)的頂級(jí)菜單項(xiàng)直接添加了一個(gè)動(dòng)作。但菜單可以是包含父子關(guān)系的樹(shù)狀菜單項(xiàng)。枝葉菜單項(xiàng)擁有一個(gè)關(guān)聯(lián)動(dòng)作,定義選中后的行為。動(dòng)作名就是在展示視圖中使用的標(biāo)題。
有好多種動(dòng)作類(lèi)型,最重要的有窗口、報(bào)表和服務(wù)端動(dòng)作。窗口(window)動(dòng)作是最常用到的,用于在客戶(hù)端中展示視圖。報(bào)表(report)動(dòng)作用于運(yùn)行報(bào)表,而服務(wù)端(server)動(dòng)作用于定義自動(dòng)化任務(wù)
這里我們關(guān)注的是用于顯示視圖的窗口動(dòng)作。剛剛創(chuàng)建的to-do清單菜單項(xiàng)使用了一個(gè)直接通過(guò)Menu Item表單創(chuàng)建的窗口動(dòng)作。我們也可以通過(guò)Settings?>?Technical?>?Actions菜單項(xiàng)查看、編輯這個(gè)窗口動(dòng)作。本例中我們感興趣的是窗口動(dòng)作菜單選項(xiàng)。
小貼士:?很多情況下,使用開(kāi)發(fā)者工具菜單中的Edit Action選項(xiàng)會(huì)更為方案,它提供了編輯當(dāng)前視圖窗口動(dòng)作的快捷方式。
配置訪問(wèn)控制權(quán)限
Odoo自帶有權(quán)限控制機(jī)制,用戶(hù)僅能使用已授權(quán)的功能。這就意味著我們創(chuàng)建的任務(wù)清單模型用戶(hù)是訪問(wèn)不到的。。
Odoo 12中的變化
****admin用戶(hù)現(xiàn)在也像其它用戶(hù)一樣受權(quán)限控制所限制。在此前的 Odoo 版本中,admin 都作為特權(quán)用戶(hù)不受權(quán)限規(guī)則控制。這一情況發(fā)生了變化,admin必須要獲得授權(quán)才能訪問(wèn)模型數(shù)據(jù)。
訪問(wèn)權(quán)限通過(guò)用戶(hù)組定義。組有時(shí)也稱(chēng)為訪問(wèn)控制列表(ACL),定義訪問(wèn)模型的權(quán)限。用戶(hù)隸屬于組。因此,每個(gè)用戶(hù)的權(quán)限依賴(lài)于其所屬組。
對(duì)這個(gè)項(xiàng)目,我們會(huì)創(chuàng)建一個(gè)to-do組,將其分配給訪問(wèn)該項(xiàng)功能的用戶(hù)。
此外,我們還可以定義記錄規(guī)則(有時(shí)稱(chēng)作行級(jí)權(quán)限),用于限制每個(gè)用戶(hù)可訪問(wèn)哪些記錄。
本項(xiàng)目中 to-do 項(xiàng)為每個(gè)用戶(hù)私有,所以用戶(hù)僅能訪問(wèn)自己創(chuàng)建的記錄。
安全組
訪問(wèn)控制基于組。通過(guò)安全組對(duì)模型設(shè)置權(quán)限,控制組內(nèi)用戶(hù)所能使用的菜單項(xiàng)。要做更精細(xì)化的控制,我們可以通過(guò)記錄規(guī)則對(duì)指定菜單項(xiàng)、視圖、字段甚至是數(shù)據(jù)記錄進(jìn)行權(quán)限控制,在下一小節(jié)中會(huì)進(jìn)行講解。
安全組還可以對(duì)應(yīng)用進(jìn)行管理,通常每個(gè)應(yīng)用有兩個(gè)組:用戶(hù)組(User)可執(zhí)行日常操作、管理員組(Manager)可對(duì)應(yīng)用執(zhí)行所有配置。
下面我們?yōu)閠o-do清單應(yīng)用新建一個(gè)安全組。
在Settings頂級(jí)菜單中,導(dǎo)航至Users & Companies > Groups,使用如下值新建一條記錄:
Application:?留空
Name:?To-do User
Inherited?標(biāo)簽下: 添加一行,選擇User types / Internal User
效果如下:

圖1.16 – To-Do User安全組
我們的安全組繼承了?Internal User組。組的繼承表示該組的成員也是所繼承組的成員,并對(duì)所有的用戶(hù)累加授權(quán)的權(quán)限。Internal User?是基礎(chǔ)權(quán)限組,通常應(yīng)用的安全組都繼承它。
在 Application 下拉列表中還沒(méi)有to-do 應(yīng)用,所以我們直接通過(guò)組表單來(lái)添加。我們還,那么這個(gè)組的成員也會(huì)自動(dòng)(遞歸)成為所繼承組的成員,以獲取他們?cè)械臋?quán)限。
**Odoo 12中的變化
**在 Odoo 12之前,Internal User組稱(chēng)作雇員(Employee),這只是表面上的修改,代碼中標(biāo)識(shí)符(XML id)仍然和此前版本相同:base.group_user。
安全訪問(wèn)控制列表
現(xiàn)在我們可以將組To-do User授權(quán)給指定模型了。
最簡(jiǎn)單的方式是使用Groups表單中的Access Rights標(biāo)簽。使用如下值添加一行:
Name:?To-do Item User Access
Object:?在列表中選擇To-do Item
勾選Read Access, Write Access, Create Access和Delete Access:勾選所有這些復(fù)選框來(lái)授予對(duì)應(yīng)的權(quán)限。
模型權(quán)限也可通過(guò)Settings > Technical > Security > Access Rights菜單進(jìn)行管理。
我們無(wú)需單獨(dú)向 Contact 模型添加權(quán)限,因?yàn)槲覀兊慕M繼承了Internal User組,已經(jīng)獲取了相應(yīng)權(quán)限。
對(duì)用戶(hù)分配安全組
現(xiàn)在可以將 admin 用戶(hù)添加到新建權(quán)限組來(lái)測(cè)試新增的權(quán)限設(shè)置:
在菜單中點(diǎn)擊Users & Companies > Users,打開(kāi)Mitchell Admin用戶(hù)的表單,點(diǎn)擊Edit。
在Access Rights標(biāo)簽下的 Other 版塊,會(huì)發(fā)現(xiàn)一個(gè)名為 To-do User 的復(fù)選框用于將用戶(hù)加入權(quán)限組。勾選后點(diǎn)擊 Save 保存表單。

圖1.17 – Mitchel Admin用戶(hù)表單
如果一切操作都正確的話(huà),我們就可以看到 To-do 應(yīng)用頂級(jí)菜單。應(yīng)該需要重新加載瀏覽器頁(yè)面強(qiáng)制刷新菜單項(xiàng)。
我們還沒(méi)有為其創(chuàng)建任何視圖,但優(yōu)秀的Odoo框架自動(dòng)為我們生成一些基本視圖:

圖1.18 – 任務(wù)清單默認(rèn)表單視圖
安全記錄規(guī)則
在對(duì)模型賦予訪問(wèn)權(quán)限時(shí),默認(rèn)用戶(hù)可以訪問(wèn)到它的所有記錄。但有時(shí)我們要限制每個(gè)用戶(hù)所能訪問(wèn)的記錄。通過(guò)記錄規(guī)則可以實(shí)現(xiàn)這一點(diǎn)。
記錄規(guī)則通過(guò)對(duì)模型定義 domain 過(guò)濾器來(lái)對(duì)讀和寫(xiě)操作進(jìn)行控制。
比如我們這里的 to-do 清單應(yīng)用,任務(wù)項(xiàng)應(yīng)為每個(gè)用戶(hù)私有的,我們不希望其他用戶(hù)看到自己的記錄。需要添加記錄規(guī)則來(lái)過(guò)濾出創(chuàng)建者自己的記錄,考慮如下幾點(diǎn):
框架會(huì)自動(dòng)添加create_uid字段,并存儲(chǔ)創(chuàng)建記錄的用戶(hù)。因此可使用它來(lái)知道每條記錄的創(chuàng)建者。
域運(yùn)行上下文包含一個(gè)user變量,其中含有當(dāng)前用戶(hù)的瀏覽器記錄。因此我們可以使用點(diǎn)號(hào)運(yùn)算符訪問(wèn)其屬性,如user.id的值。
我們可在作用域表達(dá)式中使用如下來(lái)實(shí)現(xiàn)目標(biāo):
[('create_uid', '=', user.id)]
通過(guò)菜單中的Settings > Technical > Security > Record Rules 或開(kāi)發(fā)者菜單的View Record Rules選項(xiàng)進(jìn)入記錄規(guī)則設(shè)置頁(yè)。進(jìn)行頁(yè)面后使用如下值新建記錄規(guī)則:
Name:?一個(gè)描述性的標(biāo)題,如 To-do Own Items
Model:?在下拉列表中選擇模型,此處為T(mén)o-do Item
Access Rights:?規(guī)則所授予的操作,這里保留全部勾選
Rule Definition?(Domain Filter)?:?填寫(xiě) [('create_uid', '=', user.id)]
Groups:?這部分包含所應(yīng)用的安全組。點(diǎn)擊Add a line?、選擇To-do User組
此時(shí)記錄規(guī)則的定義如下:

圖1.19 – To-do User Own Items記錄規(guī)則
此時(shí)就完成了記錄規(guī)則的設(shè)定?,F(xiàn)在可以試試用 Admin 和 Demo 用戶(hù)(需提前將 Demo 用戶(hù)加入到安全組)分別創(chuàng)建幾個(gè)任務(wù)項(xiàng)。各自應(yīng)該只能看到自己創(chuàng)建的任務(wù)了。
了解超級(jí)用戶(hù)賬號(hào)
Odoo包含一個(gè)內(nèi)置的像root那樣的超級(jí)用戶(hù),它擁有特殊權(quán)限、可不受權(quán)限控制的限制。它用于那些需忽略權(quán)限控制的內(nèi)部操作或動(dòng)作。這個(gè)超級(jí)用戶(hù)名為OdooBot,在數(shù)據(jù)庫(kù)創(chuàng)建時(shí)自動(dòng)創(chuàng)建,在數(shù)據(jù)庫(kù)中的ID為1。
Odoo 12中的變化
在Odoo 12之前。用于系統(tǒng)配置的默認(rèn)admin用戶(hù)也是超級(jí)用戶(hù)。因此,admin用戶(hù)默認(rèn)不受權(quán)限控制。在Odoo 12中進(jìn)行了調(diào)整?,F(xiàn)在,默認(rèn)的admin用戶(hù)是一個(gè)普通用戶(hù),但默認(rèn)它被設(shè)為所有Odoo應(yīng)用的管理員。
超級(jí)用戶(hù)沒(méi)有登錄密碼,但可以激活該賬號(hào)。在通過(guò)Admin \ Setting組用戶(hù)登錄時(shí),開(kāi)發(fā)者菜單中會(huì)有一個(gè)Become Superuser選項(xiàng)。
也可以直接在登錄界面進(jìn)行超級(jí)用戶(hù)模式。這時(shí)需要通過(guò)修改URL添加??debug=1來(lái)開(kāi)啟開(kāi)發(fā)者模式(如http://localhost:8069/web/login?debug=1)。然后中在**Login**按鈕下方就會(huì)出現(xiàn)**Login?as superuser**選項(xiàng)。
在啟用了超級(jí)用戶(hù)后,右上角的當(dāng)前用戶(hù)顯示為 OdooBot,該區(qū)域會(huì)變成黃黑相間的條狀,以清晰地告知用戶(hù)開(kāi)啟了超級(jí)用戶(hù)。
注意:
僅在絕對(duì)必要時(shí)才應(yīng)使用超級(jí)用戶(hù)。超級(jí)用戶(hù)不受權(quán)限控制這點(diǎn)會(huì)導(dǎo)致數(shù)據(jù)的不一致性,比如在多公司場(chǎng)景下,所以應(yīng)盡量避免。

創(chuàng)建視圖
我們創(chuàng)建了To-do Item模型,并且通過(guò)菜單項(xiàng)可在用戶(hù)界面中訪問(wèn)到它。下面我們?yōu)槠鋭?chuàng)建兩個(gè)基本的視圖:列表視圖和表單視圖。
列表視圖中用戶(hù)瀏覽已有記錄的最基本方式。有時(shí),可在列表視圖中直接編輯記錄,但更常見(jiàn)的是點(diǎn)擊記錄訪問(wèn)表單視圖來(lái)編輯記錄數(shù)據(jù)。
創(chuàng)建列表視圖
我們可在Settings > Technical > User Interface > Views中管理視圖。在該頁(yè)面點(diǎn)擊Create按鈕,輸入如下值:
View Name:?To-do List View
View Type:?Tree
Model:?x_todo_item
Architecture:這個(gè)標(biāo)簽應(yīng)包含視圖結(jié)構(gòu)的XML。使用如下XML代碼:
<tree> ?<field name="x_name" /> ?<field name="x_is_done" /> </tree>
這時(shí)視圖的定義如下所示:
圖1.20 – 任務(wù)清單列表視圖定義
列表視圖的基本結(jié)構(gòu)相當(dāng)簡(jiǎn)單,它包含一個(gè)?<tree>?
元素,內(nèi)部含有一個(gè)或多個(gè)對(duì)應(yīng)視圖中所顯示字段的?<field>?
元素。
在列表視圖中還可以做其它有趣的操作,我們會(huì)在第十章 Odoo 15開(kāi)發(fā)之后臺(tái)視圖 - 設(shè)計(jì)用戶(hù)界面中進(jìn)行更詳細(xì)的探討。
創(chuàng)建表單視圖
表單視圖也可以通過(guò)Settings > Technical > User Interface > Views創(chuàng)建。通過(guò)點(diǎn)擊Create創(chuàng)建另一條視圖記錄,填入如下值:
View Name:?To-do Form View
View Type:?Form
Model:?x_todo_item
Architecture:在該標(biāo)簽內(nèi),輸入如下XML 代碼:
<form> ?<group> ? ?<field name="x_name" /> ? ?<field name="x_is_done" /> ? ?<field name="x_work_team_ids" ? ? ? ? ?widget="many2many_tags" ? ? ? ? ?context="{'default_x_is_work_team': True}" /> ?</group> </form>
注:?如果不指定 View Type,將會(huì)通過(guò)視圖定義代碼來(lái)自動(dòng)識(shí)別。
表單視圖結(jié)構(gòu)根節(jié)點(diǎn)為<form>
元素,包含<field>
等元素。其它相關(guān)元素將在第十章 Odoo 15開(kāi)發(fā)之后臺(tái)視圖 - 設(shè)計(jì)用戶(hù)界面中進(jìn)行學(xué)習(xí)。對(duì)x_work_team_ids工作組字段,我們使用了一個(gè)指定的微件many2many_tags,它會(huì)以按扭行標(biāo)簽的形式代替普通列表顯示關(guān)聯(lián)記錄。
還可以看到在x_work_team_ids工作組字段中使用了一個(gè)context屬性。默認(rèn),關(guān)聯(lián)字段允許我們直接新建關(guān)聯(lián)中使用的記錄。因此,用戶(hù)可以通過(guò)Work Team字段直接新建Partner記錄。因?yàn)橹挥袠?biāo)記為Is Work Team??的聯(lián)系可供選擇,我們希望默認(rèn)創(chuàng)建的聯(lián)系人都啟用該標(biāo)記。這就是default_x_is_work_team上下文鍵干的事,為通過(guò)該字段創(chuàng)建的記錄設(shè)置默認(rèn)值。
這樣我們就新建好了表單視圖。如果現(xiàn)在使用To-Do?菜單項(xiàng)新建清單任務(wù)或打開(kāi)列表中已有的記錄,會(huì)看到剛剛所添加的表單視圖。
創(chuàng)建搜索視圖
我們可以在Odoo的視圖界面左上角中看到一個(gè)搜索框。搜索框讓我們可以在指定的字段中進(jìn)行搜索。在搜索框下面有Filters和Group By?按鈕,提供了一些預(yù)定義選項(xiàng)。
搜索視圖是一種控制這些行為的UI元素。它定義了在搜索框中輸入時(shí)所做的搜索以及Filters和Group By按鈕內(nèi)的選項(xiàng)。
視圖可以通過(guò)Settings > Technical > User Interface菜單或Odoo 13起開(kāi)發(fā)者菜單的Edit ControlPanelView選項(xiàng)進(jìn)行編輯,更早的版本中使用Edit Search View。
當(dāng)前任務(wù)清單模型還未定義過(guò)搜索視圖,所以我們應(yīng)當(dāng)新建一個(gè)。我們?yōu)檫^(guò)濾菜單添加一個(gè)選項(xiàng)來(lái)過(guò)濾出未完成的清單。
在新增View表單中填入如下值并點(diǎn)擊Save:
View Name:?To-do Search View
View Type:?Search
?Model:?x_todo_item
?Architecture:?在該標(biāo)簽下添加如下XML 代碼:
<search> ?<filter name="item_not_done" ? ?string="Not Done" ? ?domain="[('x_is_done', '=', False)]" /> </search>
此后,重新打開(kāi)或加載任務(wù)清單視圖時(shí),在Filters的選項(xiàng)列表中就會(huì)出現(xiàn)Not Done選項(xiàng)。
對(duì)視圖啟用默認(rèn)過(guò)濾器
默認(rèn)就開(kāi)啟這個(gè)過(guò)濾器會(huì)比較好,在不需要時(shí)刪除。
在點(diǎn)擊To-do菜單項(xiàng)時(shí),它運(yùn)行一個(gè)窗口動(dòng)作打開(kāi)To-do列表視圖。窗口動(dòng)作的context對(duì)象可用于設(shè)置默認(rèn)過(guò)濾器,類(lèi)似于對(duì)字段設(shè)置默認(rèn)值。
我們使用如下步驟:
打開(kāi)To-do菜單進(jìn)入任務(wù)清單列表視圖
打開(kāi)開(kāi)發(fā)者工具菜單并選擇Edit Action。這時(shí)將彈出一個(gè)用于打開(kāi)當(dāng)前視圖的窗口動(dòng)作表單。在General Settings標(biāo)簽欄的Filters版塊中,有一個(gè)Context Value和Domain Value字段。
在Context Value字段中,輸入?{'search_default_item_not_done': True}
search_default_?前綴指示默認(rèn)選取一個(gè)具體的過(guò)濾器,這里為item_not_done?,F(xiàn)在如果點(diǎn)擊To-do菜單項(xiàng),會(huì)看到在搜索框中默認(rèn)啟用了Not Done,并且用戶(hù)可以自由取消選擇。
Domain Value字段也可用戶(hù)對(duì)顯示的記錄設(shè)置過(guò)濾器,但設(shè)置的過(guò)濾器用戶(hù)無(wú)法移除。
小結(jié)
在本章中,我們不僅總覽了 Odoo 的組件,還利用開(kāi)發(fā)者模式深入到 Odoo 內(nèi)部來(lái)理解這些組件如何共同協(xié)作創(chuàng)建應(yīng)用。
我們還使用這些工具創(chuàng)建了一個(gè)簡(jiǎn)易的應(yīng)用,包含模型、視圖和對(duì)應(yīng)的菜單。并且學(xué)習(xí)了如何通過(guò)開(kāi)發(fā)者工具查看已有應(yīng)用或在用戶(hù)界面中直接進(jìn)行快速自定義操作。
下一章中我們將學(xué)習(xí)如何通過(guò)源碼安裝Odoo,以及準(zhǔn)備Odoo模塊開(kāi)發(fā)所使用的開(kāi)發(fā)環(huán)境。