Odoo提供了一個快速應用開發框架,非常適合創建商業應用。這類應用通常用於保留業務記錄,增刪改查操作。Odoo 不僅簡化了這類應用的創建,還提供了看板、日歷、圖表等視圖的豐富組件,用於創建好看的用戶界面。
本文主要內容有:
- 引入本文使用的學習項目:to-do (任務清單)應用
- 理解 Odoo 的結構、版本和發布,了解使用 Odoo 的相關知識
- 准備一個 Odoo 的基本工作環境,有如下選項:
- 在線Odoo
- Windows 一鍵安裝包
- Docker
- 激活開發者模式,在用戶界面中展示所需使用的工具
- 修改已有模型,添加字段,常用自定義快速入門
- 創建自定義數據模型,為我們的應用添加新的數據結構
- 配置權限,讓指定用戶組訪問應用的功能
- 創建菜單項,在用戶界面中展示新的數據模型
- 創建用戶界面的基本組件:列表、表單、搜索視圖
引入 to-do 列表應用
TodoMVC 項目提供一個多 JavaScript 框架實現的 to-do 簡單應用類比。下面我們就用 Odoo 來創建一個簡單的 to-do 應用。
使用這個應用我們可以添加新的 to-do 項,然后標記完成。比如可在項目中添加買雞蛋,然后在購買后勾選已完成。To-do 項目應僅對當前用戶可見,因而每個人可以獲取自己的 to-do 列表。對於一個簡易 to-do 應用這已足夠,但為增加點趣味性,我們還將允許 to-do 列表項目包含一組和任務相關的用戶,即工作小組。
就該應用我們應考慮以下幾層:
- 數據層:通過模型實現
- 邏輯層:通過自動化編碼實現
- 展示層:通過視圖實現 對於數據層,我們需要一個 To-do 項目模型,我們還將利用內置的 partner(或 contacts)模型來支持工作組的功能。當然還要記得在新的模型中配置訪問權限。
邏輯層中我們使用框架處理增刪改查(CRUD)基本操作,要使用框架的功能,我們需要在開發者模塊中使用 Python 代碼。對於初學者,可以使用用戶界面開發者菜單自動化工具來實現業務邏輯,后面的例子中會進行說明。
展示層中我們將為應用添加菜單項,以及 to-do 模型的視圖。業務應用的基本視圖是用於查看已有記錄的列表視圖、深入查看記錄細節的表單視圖。為增強易用性,我們還可以在列表視圖中的搜索框預置過濾項。可用搜索選項也被視為一個視圖,因而通過搜索視圖可進行實現。
以下是創建 to-do 列表應用的步驟
- 創建 to-do 項的新模型,然后添加菜單讓其可見
- 為 to-do 項模型創建列表和表單視圖,新模型包含如下字段
- Description: text 類型
- Is Done?標記:布爾型
應用的具體功能包含添加執行同一任務的一組用戶,因此需要一個表示用戶的模型。所幸 Odoo 自帶就有這樣的模型 – partner 模型(res.partner),它可用於存儲個人、公司和地址。並且僅有指定的人可被選擇加入工作團隊,因此我們需要修改 partner 模型添加Is Work Team?標記。
所以,任務清單模型還應包含一個工作團隊字段,包含一組用戶。在添加了Is Work Team?標記后這些關聯用戶可在 partners/contacts 中進行選取。
綜上,我們需要做的有:
- 為 partner 模型和表單視圖添加字段
- 創建一個 to-do 項模型
- 創建一個 to-do 應用菜單項
- 創建 to-do 項用戶界面:列表、表單視圖以及 UI 中的搜索選項
- 創建訪問權限:組、權限控制列表(ACL)和記錄規則
在落地實現之前,我們先要討論下 Odoo 框架的基本概念,然后學習如何准備工作環境。
基本概念
理解 Odoo 結構中的各個層以及我們要使用的各類型組件的作用大有裨益。下面我們先總覽下 Odoo 應用結構,然后把應用開發解構為對應組件。
然后 Odoo 發布有兩個版本的定期更新:社區版和企業版,我們應了解兩者之前的差別以及大版本發布對開發和部署所帶來的變化。首先來看看 Odoo 的應用結構:
Odoo 結構
Odoo 遵循多層結構,即前述的數據層、邏輯層和展示層:
數據層是最底端一層,負責數據持久化存儲,Odoo 借助 PostgreSQL來實現。Odoo 出於設計考慮僅支持 PostgreSQL 數據庫,而不支持MySQL 這一類數據庫(有第三方應用可集成 MySQL)。文件附件、圖片一類的二進制文件通常存儲在一個稱為 filestore(目錄) 的文件系統中。
小貼士:也就是說 Odoo 實例的完整備份需包含數據庫和 filestore 的拷貝。
邏輯層負責與數據層的所有交互,並由 Odoo 服務完成。通常,底端數據庫不應通過這一層獲取,只有這樣才能保證權限控制和數據一致性。在 Odoo的核心代碼中包含供這一接口使用的 ORM (對象關系映射Object-relational Mapping)引擎。ORM 提供插件模塊與數據交互的 API。
比如像客戶和供應商這樣的 partner 數據實體,是通過模型的 ORM 體現的。這一模型是一個 Python 對象,支持多種交互方法:create()方法用於創建新的伙伴記錄,read()方法用於查詢已有記錄和對應數據。通用方法可在特定模型中實現指定業務邏輯,如 create()方法可以設置默認值或強化驗證規則,read()方法可支持一些自動計算字段或根據執行操作的用戶來實施權限控制。
展示層用於展示數據並與用戶交互,通過客戶端實現用戶體驗。客戶端與 ORM API 交互來讀、寫、驗證或執行其它操作,通過 RPC 調用 ORM API 方法。這些操作發往 Odoo 服務器端操作,然后結果發送回客戶端做進一步處理。
對於展示層,Odoo 自帶全面功能的 web 客戶端。該客戶端支持所有業務應用所需功能:登錄會話、導航菜單、數據列表、表單等等。全局展示不會像前端工程師所認為的那樣可深度定制,但易於創建功能性和連貫的用戶體驗。配套的展示層包含網站框架,可像其它 CMS 框架一樣靈活地創建網頁,當然需要額外的操作和 web 相關知識。網站框架支持通過 web 控制器實現代碼來展示特定邏輯,而與模型內在邏輯進行區隔。前端工程師不會有什么操作上的障礙。
Odoo 服務端 API 非常開放,包含所有服務端功能。Web 客戶端使用的 API 與其它應用的 API 並無不同。因此,其它的客戶端實現均可做到,並且可以在任何平台上使用任意編程語言進行實現。可以創建桌面和移動端應用來提供不同用戶界面,這充分利用了 Odoo 為業務邏輯和數據持久性而生的數據和邏輯層。
Odoo社區版 vs. 企業版
Odoo 是這款軟件的名稱,同時也是發布軟件的公司名稱。Odoo 采取核心開源的業務模式,社區版(CE)完全免費開源,而企業版(EE)則是一款付費產品。社區版提供了全部的框架功能和大多數與 Odoo 捆綁的業務應用基礎功能。Odoo 采取 LGPL 開源協議,允許在開源模塊之上添加專屬擴展。企業版建立在社區版基礎之上,包含社區版所有功能和額外的獨有功能。值得一提的是企業版帶有一個移動端優化的用戶界面,兩個版本的用戶界面底層完全相同。Odoo 在線 SaaS 服務使用的是企業版,會部署一些企業版大版本發布之后的中間版本。
Odoo 的版本政策
在寫本文時,Odoo 的穩定版本號是13,在 GitHub 上的分支為13.0,這也是本系列文章所采用的版本。近年來 Odoo 的大版本都是按年發布, Odoo 13是在2019年10月份的 Odoo 體驗大會上發布的。官方支持最近的三個穩定版本,在13.0發布時,官方仍然維護12.0和11.0兩個版本,而停止對10.0的支持,也就是不再對 bug和安全漏洞進行修復。
應當注意 Odoo 不同大版本間的數據庫並不兼容,比如在 Odoo 11服務端運行早前版本的 Odoo 數據庫,系統將無法運行。在不同版本間遷移數據庫也頗費周折。對於插件模塊也是如此,通常老版本中開發的插件無法在新版本中生效,所以在網上下載社區模塊時,應注意選擇對應的版本。
此外,大版本(如10.0, 11.0)會被頻繁的更新,但這些通常僅僅是 bug 的修復。這些修復會確保 API 穩定,也就是模型數據結構和視圖元素標識符也會保持穩定。這點非常重要,因為這意味着我們的自定義模塊不會因上游核心模塊的不兼容修改而崩潰。
Master 分支中的版本將產生下一個穩定的大版本,但在形成穩定版之前,將不會保持 API 穩定,我們應避免使用它來創建自定義模塊。否則會如同在流沙中行進般不確定,我們無法保證什么改變會導致自定義模塊的崩潰。
基本工作環境的准備
首先我們需要一個 Odoo 實例來進行學習,本文僅要求運行一個 Odoo 實例,與具體的安裝方法無關。想要快速運行,我們可以使用一個預打包的 Odoo 發布,甚或是使用 Odoo SaaS 的試用版本。
使用 Odoo SaaS試用版本
這是最為簡便的方法,無需進行任何安裝,僅需進入官網創建一個試用數據庫。這一 Odoo 雲端軟件是基於企業版的 SaaS 服務,采用獨有的中間版本發布。在寫本文時,這一服務不僅支持試用,在僅安裝一個應用的情況下可以免費使用。SaaS 服務使用原生的 Odoo 企業版,不支持自定義模塊。在需要進行自定義時,可使用 Odoo.sh 服務,它提供一個可自定義全面功能的開發平台和主機托管方案。
注意:在 Odoo 早前版本中,社區版和企業版的菜單結構有相當大的差別,而 Odoo 12中,兩者之間的結構相近。
在 Odoo 雲端 SaaS 創建新數據庫,會需要選擇一個應用,針對本文可選擇任意應用。對於有選擇尷尬症的朋友,可以使用CRM 客戶關系管理應用。另外值得一提的是在 Odoo SaaS企業版中可選擇 Odoo Studio 應用構建器,因本系列所針對的社區版並不包含,所以我們不會用到。Odoo Studio 為開發者提供了一個用戶友好的使用界面,還有一些其它功能,如導出在模塊包中所做自定義修改。但其主要功能都可在開發者模式中獲取。
在 Windows 上安裝 Odoo
一鍵安裝包可以在Odoo官網上下載,包含各個版本及主分支,這里有 Windows 安裝包(.exe)、Debian 安裝包(.deb)和 CentOS 安裝包(.rpm)。要在 Windows 上安裝,僅需在對應版本的 nightly 文件夾中找到.exe 並進行安裝。安裝包非常方便,它包含安裝 Odoo 所需的所有部分:Python 3、PostgreSQL 數據庫、Odoo 服務端以及其它 Odoo 依賴。安裝時會創建一個 Windows 服務在開機時自動啟動 Odoo 和 PostgreSQL。
使用 Docker 容器安裝 Odoo
Docker是一個快捷運行應用的跨平台解決方案,在 MacOS, Linux 和 Windows 上均可使用。與傳統的虛擬機相比,容器技術使用更為簡單、資源利用率更高。首先需要在操作系統中安裝 Docker,可從Docker官網上下載免費使用的Docker CE(社區版),最新安裝方法可在 Docker官網上查看。
應該注意虛擬化要求在 BIOS配置中進行開啟,並且 Windows 版本的 Docker CE 需要有 Hyper-V,它僅在 Windows 10 企業版或教育版才會帶有(Windows 系統要求),而 Mac系統需要為 OS X El Capitan 10.11或更新版本。對於其它的 Windows 和 MacOS 版本,應安裝 Docker Toolbox,Docker Toolbox打包了 VirtualBox 並提供了預設置的 shell,用於作為操作 Docker 容器的命令運行環境。
譯者注:想要深入學習 Docker的朋友可參見 Alan 所翻譯的另一套書:【已完結】精通 Docker 第三版中文版
在 Odoo 商店中包含 Odoo 鏡像,在那里找到對應版本,按照提示進行安裝。要使用 Docker運行 Odoo,我們需要兩個容器,一個運行 PostgreSQL 數據庫,一個運行 Odoo 服務。
安裝通過命令行窗口完成,安裝 PostgreSQL 容器
docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:10
此時便會從互聯網上下載最新的 PostgreSQL 鏡像,並在后台開啟一個容器來進行運行。
接下來安裝 Odoo 服務容器,並且連接剛剛啟動的 PostgreSQL 容器,在本地暴露8069端口:
docker run -p 8069:8069 --name odoo --link db:db -t odoo
此時便可在終端窗口看到實時的 Odoo 服務器日志,在瀏覽器中輸入http://localhost:8069即可打開 Odoo 實例。
小貼士:如果8069端口被占用了,則Odoo 服務啟動會失敗。此時我們需要停止占用該端口的服務或者使用-p 參數指定其它端口來運行 Odoo,如修改為8070端口(-p 8070:8069)。此時可能還需要通過-d 參數修改實例所需使用的數據庫名稱。
以下Docker 的基本指令會有助於管理容器:
- docker stop 停止指定容器
- docker start 啟動指定容器
- docker start -a 啟動容器並附帶輸出,如命令終端中輸出的服務器日志
- docker attach 重新添加容器輸出至當前終端窗口
- docker ps 列出當前 Docker 容器 以上就是操作 Docker 容器的基本命令,萬一在運行容器時出現問題,可以執行如下命令(可省略 container)重新來過:
docker container stop db docker container rm db docker container stop odoo docker container rm odoo
Docker 技術的應用非常廣泛,更多知識可參見 Docker 官方文檔。
其它安裝選項
Odoo也有 Linux 系統的安裝包,包含 Debian 系(如 Ubuntu)和 Red Hat 系(如 CentOS和 Fedora)。官方文檔中有相關說明,也可參考:
-
CentOS 7快速安裝配置 Odoo 13
-
Ubuntu 快速安裝配置Odoo 13
對於源碼安裝會相對復雜,但可變性也更強,在第二章 Odoo 12開發之開發環境准備中還會詳細介紹。
創建工作數據庫
通過前面的學習,我們應該都有一個 PostgreSQL 數據庫和 Odoo 服務器供運行了。在開始使用我們的項目前還需要再創建一個 Odoo 數據庫。如果您在本地安裝 Odoo 並保留了默認設置,則可以通過http://localhost:8069/打開 Odoo。第一次打開時,還沒有可用的數據庫,此時可以看到一個用於創建數據庫的頁面:
創建數據庫需的信息有:
- Database Name:數據庫的標識名稱,在同一台服務器上可以有多個數據庫
- Email:管理員的登錄用戶名,可以不是 email 地址
- Password:管理員登錄的密碼
- Language:數據庫的默認語言
- Country:數據庫中公司數據所使用的國家,這個是可選項,與發票和財務等帶有本地化特征的應用中會用到
- Demo data:勾選此選項會在數據庫中創建演示數據,通常在開發和測試環境中可以勾選 如果在 Odoo 的服務端配置中添加了 master password,還會要求輸入該密碼。這可以阻止未經授權的用戶執行相關管理員操作,默認情況下不會設置該密碼。 點擊 Create database 按鈕后,會開始初始化數據庫,整個過程可能會需要一到幾分鍾,結束后會自動登入后台。
登錄界面底部有一個 Manage Databases 的鏈接,點擊進入會可以看到當前可用的數據庫,可對它們進行備份、復制和刪除操作,當然還可以創建新的數據庫。直接進入的地址為:http://localhost:8069/web/database/manager
小貼士:數據庫管理器可進行一些管理操作,默認開啟且沒有保護措施。雖然對於開發來說這樣非常方便,但即便是在測試或開發環境,對包含有真實數據的數據庫都存在安全風險。建議設置一個復雜的管理密碼甚至最好是關閉這一功能(在配置文件中設置 list_db = False)。
現在我們已有經了 Odoo 實例和數據庫,下一步就是開啟開發者模式這個用於實現我們項目的工具。
開啟開發者模式
要實現我們的項目,這里需要用到開發者模式所提供的工具。開發者模式使我們可以在用戶界面中直接對 Odoo 應用進行自定義操作。這有利於我們快速修改和添加功能,可用於進行一些添加字段的小調整乃至像創建帶有多個模型、視圖和菜單項的應用這樣的復雜自定義開發。
但這種直接在用戶界面執行的自定義開發相對於在后續章節講到的編程工具而言也有其局限性,如它無法添加或擴展默認的 ORM 方法(雖然有時自動化動作足以作為一個替代方案)。它也不易於集成到結構性開發流,如版本控制、自動化測試、部署到多環境(質量測試、預發布和生產環境)。
本文我們主要使用開發者模式來介紹在 Odoo 框架中應用配置是如何組織的、如何在開發者模式下進行簡單的自定義和快速列出所要實現方案的框架或原型。進入 Settings > Dashboard, 即可在右側下方看到Activate the developer mode鏈接,點擊該鏈接即可開啟開發者模式(Odoo 9.0版本及其以前的版本,開發者模式在 User 菜單的 About 對話框窗口中進行開啟)。
在該頁面我們還會看到一個Activate the developer mode (with assets)的選項,這個用於不對靜態文件進行壓縮,通常用於調試前端代碼,開啟后瀏覽的速度也會略慢。為加快加載速度,客戶端中的 JavaScript 和 CSS 文件通常會被壓縮。但這也導致我們很難對前端代碼進行調試,Activate the developer mode (with assets)選項會把這些靜態文件按照獨立文件、非壓縮的方式進行加載。
我們也可以通過修改當前的 URL 來進入開發者模式,這樣就無需進入 Settings 頁面,僅需修改鏈接中的…/web#…為…/web?debug=1#…或…/web?debug=assets#…,比如修改http:///localhost:8069/web#home為http://localhost_8069/web?debug#home。雖然沒有直接的鏈接來開啟前端框架的開發者模式,但也可以通過在前端頁面URL上添加?debug=assets 來取消靜態文件的壓縮, 但需要注意在我們進入其它頁面時這個標記可能就會消失。
小貼士:Firefox 和 Chrome均提供開啟和取消開發者模式的插件,請在火狐或 Chrome 的應用商店中搜索 Odoo debug 進行安裝
開發者模式一經開啟,在菜單中就會增加兩個選項:
- 開發者工具菜單,以調試圖標的形式出現在右上角用戶名和頭像的左側
- Settings 中的 Technical 菜單項
開發者模式還會在表單字段上添加一個額外信息:將鼠標懸停在字段上方,就會顯示一些相關技術信息。下一部分我們一起來學習相關的開發者模式功能。
為已有模型添加字段
為已有表單添加字段是種常見的自定義操作,我們無需創建自定義模塊即可在用戶界面中進行實現。就我們 To-do 應用而言,需要可以選取一組用戶對 To-do 項進行協作。我們可以通過在 partner 表單中添加標識來找到這些用戶,那么接下來為 partner 模型添加一個Is Work Team?標記。
Partner 模型是 Odoo 內核自帶的,無需安裝任何應用即可使用,但這樣在菜單中會無法查看到。一個簡單的方法是安裝 Contacts 應用。沒安裝的朋友可以點擊 Apps 菜單搜索該應用並進行安裝:
安裝完成后即可在頂級菜單中找到 Contacts 項。
為模型添加字段
開啟開發者模式后,我們可通過菜單Settings > Technical > Database Structure > Models 來查看模型的定義。這時搜索 res.partner(未安裝其它應用的情況下第一個即是),對應的模型描述為 Contact。點擊打開表單視圖,這時就可以看到 partner 模型的各類信息,包含字段列表:
點擊 Edit,然后在字段列表的最下端點擊 Add a line,即會彈出窗口用於創建新字段,輸入:
- Field Name: x_is_work_team
- Field Label: Is Work Team?
- Field Type: boolean 字段名(Field Name)必須以 x_開頭,這是在用戶界面創建模型和字段強制要求的(否則保存時會提示Custom fields must have a name that starts with ‘x_’ !),通過插件模塊的自定義開發不受這一限制。只修改添加以上信息點擊Save & Close保存即可。 這個模型有80多個字段(如未安裝 Contacts 僅50多個字段),我們需要通過右上角的向右箭頭瀏覽到最后一頁才能看到新創建的字段。這時再點擊左上角的 Save 按鈕進行最終的保存。
為表單視圖添加字段
我們已經為 partner 模型創建了新字段,但對用戶仍不可見,要實現這點我們還要在相應的視圖中進行添加操作。再回到前述的 res.partner模型詳情頁,點擊 Views 標簽,我們就可以看到模塊的各個 view 定義。正如所見,每個視圖都是一條數據庫記錄,修改或添加視圖記錄即時生效,在下一次加載視圖時即可見:
視圖列表中有一些需要注意的事項,我們看到有不同的視圖類型(View Type),如表單視圖(Form)、樹狀列表視圖(Tree)、搜索視圖(Search)和看板視圖(Kanban)。搜索視圖指的是右上角搜索框中的過濾選項。其它視圖的數據展示方法也各不相同,基本的類型有列表視圖和表單視圖(用於查看詳細信息)。
小貼士:樹狀視圖(Tree) 和 列表視圖(List) 實為同一視圖,實際上Odoo 中的為列表視圖,樹狀視圖的名稱是由歷史原因產生的 – 過去列表視圖是以樹狀層級結構來進行展示的。
可以看到同一視圖類型存在多個定義,通過 View Type 進行排序可以更清晰地看出。每種視圖類型(如表單視圖)可以有一個或多個base視圖定義(包含空的繼承視圖字段)。菜單項使用窗口動作(Window Action)可以指定要用到的base視圖,如果沒有定義,將使用排序值(Sequence)最低的,因而可將其視為默認視圖。 點擊視圖,可以在表單中看到包含排序值在內的所有詳情:
每個base視圖都可以有多個擴展,稱為繼承視圖。每個繼承視圖可以對base視圖添加修改,如對已有表單添加字段。
小貼士:繼承視圖自身也可以被其它視圖繼承,這時最外層繼承在內層繼承執行后作用於base視圖。
res.partner 模型會包含眾多的視圖定義,因為類似我們的很多應用都需要對其進行擴展。一個替代方法是進入我們需要擴展的某一具體視圖,使用開發者工具菜單對其進行編輯。這也可用於了解某一視圖在用戶界面的某處被使用了。下面我們就來進行操作:
-
點擊 Contacts 應用顯示聯系人名片列表,然后點擊任意名片進入相應的表單視圖
-
在表單視圖界面,點擊開發者工具菜單(右上角調試圖標)並選擇編輯視圖(Edit View:Form),這時可以看到與前述模型頁面相同的視圖詳情表單,但展示在實際定義使用base視圖之上。也就是res.partner.form視圖,通過External ID可以查看模塊所有者。本處為base.view_partner_form,所以我們知道這個視圖屬於base模塊。在Architecture字段中,我們可以看到base視圖定義的 XML 代碼。我們可以在這里編輯視圖結構並添加我們的新字段,但從長期看這不是一個好辦法:這個視圖屬於一個插件模塊,一旦模塊被更新,自定義的代碼就會被覆蓋並丟失。修改視圖的正確姿勢為創建一個繼承視圖(Inherited Views)擴展:
-
使用繼承視圖標簽我們可以為 base 視圖添加擴展視圖:
-
I.首先我們需要在原始視圖選擇一個元素作為擴展點,我們可以通過查看 base視圖的結構選擇一個包含 name 屬性的 XML 元素,大多數情況選擇的是一個
<field>
元素,此處我們選擇<field name=”category_id”…>
元素: -
II.現在,點擊開發者工具菜單,然后點擊編輯視圖(Edit View:Form),選擇繼承視圖(Inherited Views)標簽回到前述的界面,然后點擊最下方的 Add a line鏈接
-
III.此時會彈出名為Create Views which inherit from this one的窗口,填入如下內容
- View Name: Contacts – Custom “Is Work Team” flag
- Architecture:輸入如下 XML代碼
<field name="category_id" position="after"> <field name="x_is_work_team" /> </field>
-
其它重要字段,如 Model, View Type 和 Inherited View 使用默認值即可 IV.此時點擊 Save & Close按鈕,然后在Edit View: Form 窗口點擊Save按鈕
在保存修改后重載聯系人表單視圖頁面即可查看到變化,在大數瀏覽器中可以使用 F5快捷鍵來重載頁面。這時打開任意聯系人名片,可以看到右側 Tags 字段下會多出一個新字段:
創建新的模型(Model)
模型是應用的基本組件,包含了所需使用到的數據結構和存儲。接下來我們就為 To-do 項目添加模型,將包含三個字段:
- Description
- Is done? 標記
- Work team 用戶列表 如前所述,通過菜單Settings > Technical > Database Structure > Models可進入模型創建頁面,步驟如下:
1、進入模型菜單,點擊左上角 Create 按鈕,在彈出頁面填入
* Model Description: To-do Item * Model: x_todo_item * 在進一步添加字段之前可以先進行保存。
2、點擊 Save 保存然后點擊 Edit 再次進入編輯,可以看到 Odoo 自動添加了一些字段,ORM在所有模型中添加了這些字段,可用於審計和記錄功能。
x_name (或Name)字段是在列表中顯示記錄或其它記錄中引用時顯示的標題。在 To-do Item標題中將使用它,還可以對其進行編輯將字段標簽改為更能表達含義的描述。基於前面的知識添加 Is Done? 標記此時就顯得非常容易了。
3、在字段列表頁底部點擊 Add a line 鏈接創建一個包含如下值的字段:
- Field Name: x_is_done
- Field Label: Is Done?
- Field Type: boolean
該字段的填寫效果如下:
接下來添加 Work Team 字段就帶有挑戰性了,不僅因為這是一個指向 res.partner 對應記錄的關聯字段,它還是一個包含多個值的 selection 字段。在很多框架中這都會頗為復雜,但所幸我們使用的是 Odoo,因為它支持 many-to-many 關聯。任務清單應用屬於這一情況,因為一條任務可以有多個用戶,同時一個用戶也可以參與多個任務。
4、再次在字段列表中點擊 Add a line,添加一個包含如下值的字段:
- Field Name: x_work_team_ids
- Field Label: Work Team
- Field Type: many2many
- Object Relation: res.partner
- Domain: [(‘x_is_work_team’, ‘=’, True)]
many-to-many字段有其獨有的定義項-Relation Table, Column 1, and Column 2項,這些值會被自動填充,大多數情況下都無需修改。在第六章 模型 – 結構化應用數據中將會有更詳細的探討。 Domain 項為非必填項,這里使用到是因為只有符合條件的用戶才可被選取加入工作組,如果不加這項則所有用戶均可被選取。
Domain 表達式中對展示的記錄進行了過濾,它遵循Odoo 獨有的語法 – 一個包含三個值的元組(補充:經測試使用列表也同樣可以),第一項為待過濾的字段名、第二項為過濾操作符、第三項為過濾作用的值。詳細的解釋參見第七章 記錄集 – 使用模型數據。
小貼士:Odoo有一個交互式的 domain 過濾向導可幫助生成 domain 表達式。訪問Settings > Technical > User Interface > User-defined Filters,點擊 Create選擇模型后將會出現 Add filter 按鈕,可通過選擇字段在下方的文本框中實時生成 domain 表達式。
現在我們已經為 To-do應用創建好了模型,但還無法使用它,在創建模型后,我們需要配置組來使用該模型。
配置安全權限控制
Odoo自帶有權限控制機制,用戶僅能使用被授權了的功能。這就意味着我們自建的庫功能不對普通用戶甚至是管理員開放。
注意:Odoo 12開始的修改 管理員用戶現在也像其它用戶一樣受權限控制所限制。在此前的 Odoo 版本中,admin 都作為特權用戶不受權限規則控制。而新版中我們需要進行授權管理員才能訪問模型數據
Odoo 安全權限通過安全組來設置訪問權限。每個用戶的權限根據所屬組來決定,對於我們的測試項目,我們將創建一個 to-do 用戶組,然后通過組來分配可使用功能的用戶。我們通常使用 ACL 為某個組賦予指定模塊的讀或寫權限,就當前項目,我們對添加的 to-do 項模型添加讀和寫權限。
此外,我們還可以設置用戶對指定模型的記錄范圍的訪問規則。本項目中 to-do 項為用戶私有,所以用戶僅能訪問自己創建的記錄,這通過安全記錄規則實現。
安全組
訪問控制基於組,通過安全組對模型設置權限,控制組內用戶所能使用的菜單項。要做更精細化的控制,我們可以對指定菜單項、視圖、字段甚至是(帶有記錄規則的)數據記錄進行權限控制。
安全組還可以對應用進行管理,通常每個應用有兩個組:用戶組(Users)可執行日常操作、管理員組(Manager)可對應用執行所有配置。
下面我們新建一個安全組,在菜單中訪問Settings > Users & Companies > Groups。點擊 Create通過如下值創建一條新記錄:
- Application: 留空
- Name: To-do User
- Inherited 標簽下: 添加User types / Internal User項 效果如下:
在 Application 下拉列表中還沒有to-do 應用,所以我們直接通過組表單來添加。我們還繼承了 Internal User 用戶組,那么這個組的成員也會自動(遞歸)成為所繼承組的成員,以獲取他們原有的權限。Internal User 是基礎權限組,通常應用的安全組都繼承它。
注意:Odoo 12的修改 在 Odoo 12之前,內部用戶組稱作雇員(Employee),這只是表面上的修改,代碼中標識符(XML id)仍然和此前版本相同:base.group_user。
安全權限控制列表
現在我們可以對指定組(To-do User)進行指定模型的權限授予,在上述表單的Access Rights標簽下添加一條記錄,對應的值為:
- Name: To-do Item User Access
- Object: 在列表中選擇To-do Item
- 勾選Read Access, Write Access, Create Access, and Delete Access
模型權限也可通過Settings > Technical > Security > Access Rights進行管理。我們無需向 Partner 模型添加權限,因為我們的組繼承了內部用戶組,已經獲取了相應權限。
現在可以將 admin 用戶添加到新建組來測試新加的權限設置
1、在菜單中點擊Users & Companies > Users,從用戶列表中選擇Mitchell Admin,然后編輯表單
2、在Access Rights標簽下的 Other 版塊,會發現一個名為 To-do User 的復選框用於讓用戶加入權限組,勾選后點擊 Save 保存表單。
如果一切操作都正確的話,我們就可以看到 To-do 頂級菜單,用於添加任務清單項,並且我們只能訪問自己的任務清單而看不到其它人的。(請先執行創建菜單項部分再進行查看)
安全記錄規則
在對模型賦予訪問權限時,默認用戶可以訪問到他的所有記錄。但有時我們要限制每個用戶所能訪問的特定記錄。通過記錄規則可以實現這一點,通過定義 domain 過濾器來對讀和寫操作進行控制。
比如我們這里的 to-do 應用,任務項應為用戶私有,我們不希望其他用戶看到自己的記錄。需要添加記錄規則來過濾出創建者自己的記錄:
框架會自動添加create_uid字段,並存儲創建記錄的用戶,通過該字段可以確定每條記錄的創建者 在user變量中可獲取到當前用戶,user 變量讀取上下文中 domain 過濾器過濾后的對象 通過[(‘create_uid’, ‘=’, user.id)]域表達式可實現這點。通過菜單中的Settings > Technical > Security > Record Rules 進入記錄規則設置頁,點擊 Create 並輸入如下值:
- Name: 一個描述性的標題,這里使用 To-do Own Items
- Object: 在列表中選擇模型,此處為To-do Item
- Access Rights: 規則所授予的操作,這里保留全部勾選
- Rule Definition:
- 域過濾器,填寫 [(‘create_uid’, ‘=’, user.id)]
- Groups: 作用的安全組,選擇To-do User組
此時就完成了記錄規則的設定,現在可以試試用 Admin 和 Demo 用戶(需提前將 Demo 用戶加入到安全組)分別創建幾個任務項,各自將只能看到自己創建的任務。記錄規則可通過右上角的切換按鈕進行關閉,一旦關閉,用戶就可以看到所有人的任務清單了。
超級用戶賬號
在此前的 Odoo 版本中,admin 用戶是一個特權用戶可以不受權限控制。Odoo 12就此做了調整,admin 用戶屬於所有用戶安全組,但只是個普通用戶。還是存在一個超級用戶不受權限控制,但它無法直接登錄。
我們還是能以超級用戶進行操作,當一個用戶以 Administration / Settings 用戶組登錄時,開發者工具菜單中有一個 Become Superuser選項,或者在登錄頁面開啟開發者模式,則會出一個Login as superuser的隱藏按鈕。
在激活了超級用戶后,右上角的當前用戶顯示為 OdooBot,該處背景也會變成黃黑間隔的條狀,以清晰地告知用戶激活了超級用戶。僅在絕對必要時才應使用這一操作,超級用戶不受權限控制這點會導致數據的不一致,比如在多公司場景下,所以應盡量避免。
創建菜單項
現在有了存儲任務清單的模型,應在用戶界面中顯示它,添加菜單項可實現這一點。我們這里創建一個頂級菜單項直接打開任務清單,一些像聯系人(Contacts)這樣的應用采取了這種方式,但另外一些則使用了在頂欄中的子菜單項。
注意:Odoo 12的修改 社區版中第一級以下的菜單項也像企業版中一樣顯示在了頂欄中,而此前版本社區版的菜單項顯示在屏幕的左側。
點擊菜單Settings > Technical > User Interface > Menu Items,點擊 Create 即可進入菜單的編輯頁面。在該頁面中輸入如下值:
- Menu: To-do
- Parent Menu: 留空
- Action: 選擇ir.actions.act_window,然后在右側下拉框中點擊Create and Edit打開一個相關的窗口操作表單 在彈出的表單中填入
- Action name: To-do Items
- Object: x_todo_item (目標模型的編碼標識)
保存所有打開的表單,此時即可在菜單中使用 To-do 應用了 要在菜單中顯示該項,需要重載客戶端頁面,大多數瀏覽中可使用快捷鍵 F5(強制刷新:Windows: Ctrl+F5, Mac: Cmd+F5)。現在就可以訪問菜單項並進行任務清單模型的交互了。雖然我們沒有創建視圖,但強大的 Odoo 框架自動為我們生成了一個基礎視圖:
在本例中,在頂級菜單中直接添加了一個操作,而沒有子菜單。但菜單可以包含一系列帶有父子關系的菜單項,最末級菜單項關聯一個動作(Action),定義有選取時執行的行為。 動作名將作為所展示視圖的標題。
有很多的操作類型,最重要的有窗口(window)、報表(reports)和服務端(server)動作。窗口動作最常用,用作在客戶端中展示視圖,報表動作用於運行報表,服務端動作用於定義自動化任務。
截至目前,我們都聚焦在顯示視圖的窗口動作上,正是使用了直接在菜單項表單中創建的窗口操作來創建了任務清單的菜單項。我們也可以在Settings > Technical > Actions中查看和編輯動作,在本例中僅需使用窗口操作。
小貼士:很多情況下使用開發者工具中的 Edit Action 選項更為方便,它提供一個編輯當前視圖窗口操作的快捷方式。
接下來我們進入到下一部分,創建我們的視圖。
創建視圖
前面我們創建了一個任務清單模型通過菜單項在用戶界面中顯示,接下來我們為它創建兩個基本視圖:列表視圖和表單視圖。
列表視圖
創建列表視圖步驟如下:
1、點擊Settings > Technical > User Interface > Views,點擊 Create 進入視圖編輯頁面,填入如下值:
- View Name: To-do List View
- View Type: Tree
- Model: x_todo_item 效果如下:
2、在Architecture標簽下,使用 XML 書寫視圖的結構,代碼如下:
<tree> <field name="x_name" /> <field name="x_is_done" /> </tree>
列表視圖的基本結構非常簡單:一個包含列表視圖中顯示的一個或多個數據列的元素(element)。在列表視圖還有一些有意思的選項,將在第十章 后台視圖 – 設計用戶界面中詳細探討。
表單視圖
創建表單視圖的步驟如下:
1、創建另一條視圖記錄,並填入如下值:
- View Name: To-do Form View
- View Type: Form
- Model: x_todo_item >小貼士:如果不指定 View Type,將會通過視圖定義代碼來自動識別。
2、在Architecture標簽下, 輸入如下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>
表單視圖結構根節點有一個<form>
元素,包含<field>
元素,其它相關元素將在第十章 后台視圖 – 設計用戶界面中進行學習。這里還有一個針對工具組字段的小組件(widget),以標簽按鈕而非列表欄顯示。這一個按鈕狀標簽通過在工作組字段中添加 widget 屬性來實現。
默認情況下,關聯字段允許直接創建記錄用作關聯。也就說可以在工作組字段中直接創建用戶,但如果這么做用戶將不會帶有Is Work Team? 標記,也就產生了不一致性。
為了更好的用戶體驗,在這種情況下我們可以默認就帶有這一標記。這需要通過 context 屬性來實現,它向下一個視圖傳遞 session 信息,比如要使用的默認值。在后續章節中會就此進行探討,現在只要知道這是一個鍵值對的字典即可。以 default_作為前綴來提供對應字段的默認值。 所以此處要為用戶設置Is Work Team? 標記所需的表達式為{‘default_x_is_work_team’: True}。
此時點擊 To-do菜單進行創建或打開已有清單則會顯示為我們所創建的視圖。
搜索視圖
我們可以為列表視圖右上角的搜索框預設一些過濾項和分組選項,Odoo 把這也視為視圖元素,所以可以像列表視圖和表單視圖一樣在 Views 中添加記錄來定義。想必現在大家已經非常熟悉了,在菜單中點擊Settings > Technical > User Interface > Views 或在開發者工具中對應上下文中進行編輯操作均可。我們進入任務清單列表視圖,點擊開發者工具中的Edit Search View。
當前列表清單模型還未定義過任何搜索視圖,所以顯示一個空表單用於進行創建,填入如下值並保存:
- View Name:選擇一個有意義的描述,此處使用To-do Items Filter
- View Type: Search
- Model: x_todo_item
- Architecture: 添加如下XML 代碼:
<search> <filter name="item_not_done" string="Not Done" domain="[('x_is_done', '=', False)]" /> </search>
此時重載任務清單,可以在搜索框下方 Filters 按鈕下選擇預設的 Not Done 過濾器,在搜索框中輸入 Not Done也會提示過濾條件。默認開啟過濾器會較便捷,在不需要時取消過濾即可。正如默認字段值一樣,還是使用 context 屬性來設置默認過濾器。
在點擊 To-do 菜單時,執行一個窗口操作打開列表視圖,該操作可設置一個上下文值,讓視圖默認開啟某一搜索過濾器,操作步驟如下:
- 點擊To-do 菜單進入任務清單列表
- 點擊開發者工具圖標並選擇Edit Action,這時將彈出一個窗口操作界面,在右下角有一個 Filters版塊,這里有 Domain 和 Context 字段。
- Domain 字段可用於為所顯示記錄設置固定的過濾器,而且用戶無法刪除。這不符合我們的場景。我們只是要默認開啟item_not_done過濾器,用戶可以隨時取消選擇。默認打開過濾器,添加以search_default_作為前綴的 context 鍵,這里使用{‘search_default_item_not_done’: True}
這時再點擊 To-do 菜單,搜索框中默認就會開啟 Not Done 過濾器。
總結
在本文中,我們不僅概覽了 Odoo 組件的組織方式,還利用開發者模式深入到 Odoo 內部來理解這些組件如何共同協作創建應用。
我們還使用這些工具創建了一個簡易的應用,包含模型、視圖和對應的菜單。並且掌握了通過開發者工具可以查看當前應用或在用戶界面中直接進行快速自定義操作。
下一篇中我們將更深入地了解 Odoo 開發,並學習如何設置和組織開發環