第三章 Odoo 12 開發之建立第一個 Odoo 應用

Odoo 開發一般都須要建立本身的插件模塊。本文中咱們將經過建立第一個應用來一步步學習如何在 Odoo 中開啓和安裝這個插件。咱們將從基礎的開發流學起,即建立和安裝新插件,而後在開發迭代中更新代碼來進行升級。html

Odoo 採用類 MVC(Model-View-Controller)的結構,咱們將深刻到各層來實施一個圖書應用。本文主要內容有:前端

  • 建立一個新的模塊,用來實施相關功能
  • 添加應用的特性功能:頂級菜單項和安全組
  • 添加一個一開始會失敗但在項目完成時成功運行的自動化測試
  • 實施模型層,定義應用的數據結構和相關訪問權限
  • 實施後臺視圖層,編寫內部用戶界面
  • 實施業務邏輯層,支持數據驗證和自動化
  • 實施 web 層,展現訪客和內部用戶的用戶界面

 

系統準備

本文要求安裝了 Odoo 服務並可經過命令行啓動服務來進行模塊安裝和運行測試之類的操做。若是尚未相關環境,請參照本系列文章第二篇Odoo 12開發之開發環境準備git

本文中咱們將從零開始建立第一個 Odoo 應用,無需額外的代碼。本文代碼可經過 GitHub 倉庫進行查看。github

概覽圖書項目

爲更好地在本文中探討,咱們將使用一個現實中可使用的學習項目。一塊兒來建立一個管理圖書庫的 Odoo 應用。該項目將在後續文章中持續使用,每篇文章都會進行一次迭代,爲應用添加新的功能。本文中將建立圖書應用的第一個版本,第一個功能是實現圖書目錄。web

圖書將包含以下數據:算法

  • 標題
  • 做者
  • 出版社
  • 發行日期
  • 封面圖
  •  ISBN:包含檢查 ISBN是否有效的功能
  • 有效性標記;標識圖書是否已對公衆發佈

圖書目錄可由圖書管理員編輯,對圖書操做者則僅有可讀權限。該目錄可經過公共網頁訪問,僅顯示已發佈圖書。就是這樣一個簡單的項目,但提供有用的功能,足以讓咱們瞭解 Odoo 應用的主要構件。數據庫

建立新的插件模塊

一個插件模塊是包含實現一些 Odoo 功能的文件夾,能夠添加新功能或修改已有的功能。插件目錄必須含有一個聲明或描述文件__manifest__.py,以及其它模塊文件。編程

一部分模塊插件在 Odoo 中以app的形式出現,一般都會帶有頂級菜單項。它們爲 CRM 或 HR 這樣的功能區添加核心元素,所以在 Odoo 應用菜單中會高亮顯示。另外還有一些非應用模塊插件通常爲這些應用添加功能。若是你的模塊爲 Odoo 添加新的或重要的功能,通常應該是app。而若是模塊僅修改應用的功能,那麼就是一個普通的插件模塊。sublime-text

要建立新模塊,須要:api

  1. 確保操做的目錄是 Odoo 的 addons 路徑
  2. 建立模塊目錄,幷包含聲明文件
  3. 可選擇爲模塊添加一個圖標
  4. 如打算對外發布,爲模塊選擇一個證書

而後咱們就能夠安裝模塊了,肯定模塊在 Odoo 服務中可見並正確安裝它。

準備 addons 路徑

一個插件模塊是一個含有 Odoo 聲明文件的目錄,它建立一個新應用或爲已有應用添加功能。addons模塊的路徑是一系列目錄,Odoo 服務能夠在這裏查找插件。默認addons包含odoo/addons 中存放的 Odoo 自帶的官方應用,以及在odoo/odoo/addons目錄中提供核心功能的 base 模塊。

咱們應將本身建立的或應用市場及其它地方下載的模塊放到指定的目錄中。要使得 Odoo 服務可以找到這些應用,須要這些目錄添加到 Odoo 的 addons 路徑中。

根據咱們在Odoo 12開發之開發環境準備所建立的項目,Odoo 的代碼存放在~/odoo-dev/odoo/目錄下。最佳實踐告訴咱們應在自有目錄下添加代碼,而不該與 Odoo 源代碼混在一塊兒。因此要添加自定義模塊,咱們將在 Odoo 同級建立目錄~/odoo-dev/custom-addons並添加到 addons 路徑中。要添加該目錄至 addons 路徑,執行以下命令

注:若有報錯參照Odoo常見問題彙總開發類錯誤處理001

–save 參數將選項保存至配置文件中,這樣咱們就無需在每次啓動服務時輸入參數,只需運行./odoo-bin 便可使用上次使用的參數。能夠經過-c 參數指定文件來使用或保存配置項。仔細查看輸出的日誌,能夠看到INFO ? odoo: addons paths:[…] 一行中包含custom-addons目錄。

如需使用其它目錄也請添加至 addons 路徑,好比有~/odoo-dev/extra 目錄中包含需用到的目錄,則需經過以下方式設置–addons-path參數:

如今咱們須要讓 Odoo 實例能識別新模塊。

小貼士:以上使用的是相對路徑,但在配置文件中需使用絕對路徑,–save 參數會自行進行轉化。

建立模塊目錄和聲明文件

如今就準備好了~/odoo-dev/custom-addons目錄,已正確添加至 addons 路徑,Odoo 也就能夠找到這裏的模塊。Odoo 自帶一個scaffold命令可自動建立新模塊目錄,其中會包含基礎結構。此處並不會使用該命令,而是手動建立。經過如下命令能夠了解scaffold用法:

Odoo 模塊目錄需包含一個__manifest__.py描述性文件,同時還須要是可導入的包,因此還應包含__init__.py文件。

ℹ️在老版本中,該描述性文件爲__openerp__.py或__odoo__.py,這些名稱已過期但仍可以使用。

模塊目錄名是其技術名稱,咱們使用library_app,技術名稱應是有效 Python 標識符,即以字母開頭且僅能包含字母、數字和下劃線。執行以下步驟來初始化新模塊:

一、經過命令行,咱們能夠添加一個空的__init__.py 文件來初始化模塊:

二、下面添加聲明文件,其中應包含一個 Python 字典,有幾十個可用屬性。其中僅 name屬性爲必填,但推薦同時添加 description 和 author 屬性。在__init__.py 同級建立__manifest__.py 文件,添加如下內容:

depends 屬性能夠是一個包含所用到的模塊列表。Odoo 會在模塊安裝時自動安裝這些模塊,這不是強制屬性,但建議使用。若是沒有特別的依賴,能夠添加內核 base 模塊。應注意將全部依賴都在此處列明,不然,模塊會因缺乏依賴而報錯或出現加載錯誤(若是碰巧依賴模塊在隨後被加載了)。

咱們的應用無需依賴其它模塊,因此本處使用了 base。爲保持簡潔,這裏僅使用了幾個基本描述符鍵:

  • name:插件模塊標題字符串
  • description:功能描述長文件,一般爲RST格式
  • author:做者姓名,本處爲一個字符串,能夠是逗號分隔的一系列姓名
  • depends:一個依賴插件模塊列表,在模塊安裝時會先安裝這些插件
  • application:一個布爾型標記,表明模塊是否在應用列表中以 app 展示

description可由模塊頂層目錄中的README.rst或README.md代替,若是二者都不存在,將使用聲明文件中的description。

在真實場景中,建議也同時使用其它屬性名,因它們與 Odoo 的應用商店有關:

  • summary:顯示爲模塊副標題的字符串
  • version::默認爲1.0,應遵照版本號規則。建議在模塊版本號前加上 Odoo 版本,如12.0.1.0
  • license::默認爲LGPL-3
  • website:瞭解模塊更多信息的 URL,能夠幫助人們查看更多文檔或提供文件 bug 和建議的跟蹤
  • category::帶有模塊功能性分類字符串,缺省爲Uncategorized。已有分類可經過安全組表單(位於Settings > Users & Companies > Groups)的 Application字段下拉列表查看(需開啓調試模式)

Odoo 12 開發之建立第一個 Odoo 應用

還有如下描述符鍵:

  • installable:默認爲 True,但能夠經過設置爲 False 來禁用模塊
  • auto_install:若設置爲 True,在其依賴已安裝時會自動安裝,用於膠水模塊,用於同一實例上兩個模塊安裝後功能的鏈接。

添加圖標

模塊可選擇添加圖標,這對於做爲 app 的模塊尤爲重要,由於在應用菜單中通常都應有圖標。要添加圖標,須要在模塊中添加static/description/icon.png文件。

爲簡化操做,咱們能夠複用 accounting 應用的圖標,把odoo/addons/account/static/description/icon.png文件拷貝至customaddons/library_app/static/description目錄。可經過以下命令完成:

補充:開啓開者發者模式(修改 URL 中web#爲web?debug#),點擊 Apps > Update Apps List便可搜到咱們建立的應用(下圖我使用了自定義的圖標)

Odoo 12 開發之建立第一個 Odoo 應用

選擇證書(開源協議)

爲開發的模塊選擇證書(開源協議)很是重要,應謹慎考慮其表明着什麼。Odoo 模塊最經常使用的協議是LGPL(GNU Lesser General Public License)第3版(LGPL v3.0)和AGPL(Affero General Public License)。

LGPL 受權更廣,它容許在無需分享相應源碼的狀況下對代碼做出商業修改。AGPL則是一個更嚴格的開源證書,它要求派生代碼及服務託管者分享源碼。

瞭解更多有關 GNU 證書請訪問GNU官網

安裝新模塊

如今咱們已經有了一個簡化的模塊,尚未任何功能,但咱們能夠經過安裝它來檢查各項是否正常。

要進行這一操做,模塊全部的插件目錄應對 Odoo 服務可見。能夠經過啓動 Odoo 服務來進行確認,能夠在輸出第一行看到顯示爲odoo: addons paths: xxx 字樣,其中會顯示在用的插件路徑。更多有關插件路徑的知識,參見本系列文章第二篇 Odoo 12開發之開發環境準備

要安裝新的模塊,咱們應在啓動服務時指定-d 和-i 參數,-d 指定應使用的數據庫,-i 可接收一個逗號分隔的多個待安裝模塊名。假定開發數據庫爲dev12,則使用以下命令進行安裝:

仔細看日誌輸出可肯定模塊是否能被找到並安裝,正確安裝對應日誌: odoo.modules.registry: module library_app: creating or updating database tables。

更新模塊

開發模塊是一個不斷迭代的過程,咱們會須要應用更新所修改代碼並在 Odoo 中可見。能夠在後臺界面Apps中搜索對應模塊並點擊 Upgrade 按鈕。但若是修改的是 Python 代碼,點擊升級不會生效,須要先重啓服務方可生效。這是由於 Odoo 僅會加載一次 Python 代碼,此後的修改就要求進行重啓纔會生效。

有時,模塊中既修改了數據文件又修改了 Python 代碼,那麼就須要同時進行如上兩種操做。這是 Odoo 開發者的常見困惑。幸虧還有更好的方式,最保險的方式是重啓 Odoo 實例並應用升級至開發數據庫。經過Ctrl + C中止服務實例,而後經過以下命令啓動服務並升級library_app模塊:

-u(或全稱–update)要求使用-d 參數並接收一個逗號分隔的待升級模塊集。例如可使用-u library_app,mail。模塊升級後,全部依賴該模塊的模塊也會被升級。這是保持用於擴展功能的繼承機制完整性的基礎。

Odoo 11中的修改:
直到 Odoo 10.0,要安裝新的插件模塊,須要在後臺客戶端菜單中手動更新以對 Odoo 可見。從 11.0開始,模塊列表在模塊安裝或更新時會自動更新。

在本系列文章中,如需應用對模塊代碼的修改:

  • 添加模型字段時需進行升級。修改 Python 代碼(含 manifest 文件)時須要重啓服務。
  • 修改XML或CSV文件時,需進行升級。在不肯定時,同時重啓服務並升級模塊。

在不肯定時,最保險的方式是經過-u參數來重啓 Odoo 實例,按下鍵盤上、下方向鍵可在使用過的命令間切換。進行這一操做時,咱們常常會使用到 Ctrl+C,向上方向鍵和Enter 鍵。

或者要避免這種重複的中止/啓動操做,可以使用dev=all選項。這樣在保存XML 和 Python文件修改時會自動進行重載,參見本系列文章第二篇 Odoo 12開發之開發環境準備瞭解更多詳情。

建立新應用

一些 Odoo 模塊建立新應用,而另外一些則對已有應用添加功能或做出修改。雖然二者的技術組件基本相同,但應用會被預期包含一些特徵性元素。咱們建立的是一個圖書應用,因此應包含這些元素,它們是:

  • 圖標:用於在應用列表中展現
  • 頂級菜單項:其下放置全部的應用菜單項
  • 應用安全組:經過權限訪問僅對指定用戶開放

添加圖標(icon),僅需在模塊目錄下static/description/子文件夾中放置icon.png文件,前面已經介紹過了。下面咱們來添加應用頂級菜單。

添加應用頂級菜單項

咱們建立的是一個新應用,所以應包含主菜單項,在社區版本中,顯示在左側下拉菜單中,而在企業版中,則做爲附加圖標顯示在應用切換器主界面中。

菜單項是使用 XML 文件中添加的視圖組件,經過建立views/library_menu.xml來定義菜單項:

用戶界面中的菜單項和操做均存儲於數據表中,上面的代碼是一個 Odoo 數據文件,描述了要載入 Odoo 數據庫的記錄。其中的元素是向ir.ui.menu模型寫入記錄的指示。 id 屬性也稱做XML ID,用於惟一標識每一個數據元素,以供其它元素引用。例如在添加圖書子菜單時,就須要引用頂級菜單的XML ID,即menu_library。XML ID是一個重要話題,將在本系列文章第五篇Odoo 12開發之導入、導出以及模塊數據中探討。

此處添加的菜單項很是簡單,僅用到了 name 屬性。其它經常使用的屬性這裏沒有使用,沒有設置父菜單,由於這是一個頂級菜單。也沒有設置 action,因菜單項自己並不作任何事,僅僅用於放置後面要建立的子菜單項。模塊還不知道 XML 數據文件的存在,咱們須要在__manifest__.py中使用 data 屬性來添加安裝或更新時須要加載的模塊列表以進行聲明。在manifest 文件的字典中加入:

要向Odoo數據庫中加載這些菜單設置,須要升級模塊。此時還不會有什麼顯式的效果,因菜單項還不包含可操做子菜單,因此不會顯示。在添加好子菜單及合適的訪問權限時便可顯示。

小貼士:菜單樹中的項目僅在含有可見子菜單項時纔會顯示。底層包含窗口操做視圖的菜單項僅當用戶擁有該模型訪問權限時纔可見。

添加權限組

普通用戶在使用功能前需得到相應的權限。Odoo 中使用安全組來實現,權限授予組,組中分配用戶。Odoo 應用一般有兩個組:針對普通用戶的用戶組,包含額外應用配置權限的管理員組。

下面咱們就來添加這兩個安全組。權限安全相關的文件一般放在模塊下/security子目錄中,這裏咱們建立security/library_security.xml 文件來進行權限定義。安全組使用分類來更好地組織關聯應用。因此第一步咱們在ir.module.category模型中建立針對圖書應用的分類:

下一步,咱們要添加兩個安全組,首先添加用戶組。在以上結束標籤前添加以下 XML 代碼塊:

記錄在res.groups模型中建立,添加了三個字段:

  • name:組名
  • category_id:關聯應用,這是一個關聯字段,所以使用了 ref 屬性來經過 XML ID 鏈接已建立的分類
  • implied_ids:這是一個one-to-many關聯字段,包含一系列組來對組內用戶生效。這裏使用了一個特殊語法,在本系列文章第五篇Odoo 12開發之導入、導出以及模塊數據中會進行介紹。咱們使用了編號4來鏈接基本內部用戶組base.group_user。

而後咱們建立管理員組,授予用戶組的全部權限以及爲應用管理員保留的其它權限:

像用戶組同樣,這裏也有name, category_id和implied_ids ,implied_ids關聯了圖書用戶組,以繼承其權限。還添加了一個 users 字段,讓管理員和內部 root 用戶自動成爲應用管理員。

ℹ️在 Odoo老版本中,admin 管理員用戶同時也是 root 用戶。Odoo 12中有一個系統 root用戶,在用戶列表中不顯示,僅在框架須要進行提權(sudo)時在內部使用。admin能夠登入系統並應擁有全部功能的訪問權限,但再也不像系統 root 用戶那樣能夠繞過訪問限制。

一樣須要在聲明文件中添加該 XML 文件:

注意library_security.xml 加在library_menu.xml文件以前,數據文件的加載順序很是重要,由於咱們只能引用已經定義過的標識符。菜單項常常引用到安全組,因此建議將安全組定義文件放到菜單和視圖文件以前。

Odoo 12 開發之建立第一個 Odoo 應用

添加自動化測試

編程的最佳實踐包含代碼的自動化測試,對於像 Python 這樣的動態語言尤其重要,由於它沒有編譯這一步,只有在解釋器實際運行代碼時纔會報語法錯誤。好的編輯器可讓咱們提早發現問題,但沒法像自動化測試這樣幫助咱們肯定代碼如預期般運行。

Odoo 12中的修改
在老版本中,Odoo 使用YAML文件來進行測試,但 Odoo 12中移除了對YAML文件的支持,因此不能再使用該格式文件。

測試驅動開發(TDD -Test-driven Development) 方法讓咱們先寫測試,檢查錯誤,而後開發代碼直至經過測試。受此方法啓示,在添加實際功能前咱們先添加模塊測試:

一、測試代碼文件名應以test_開頭,並經過tests/__init__.py引用。但測試目錄(也即 Python 子模塊)不該在模塊的外層__init__.py中引入,由於僅在測試執行時纔會自動查找和加載它。

二、測試應放在tests/子目錄中,在tests/__init__.py中添加以下代碼:

三、在tests/test_book.py文件中添加實際的測試代碼:

以上代碼添加一個簡單測試用例,建立一本新書並檢測active 字段的值是否正確。

四、使用–test-enable參數在安裝或升級模塊時進行測試

五、Odoo 服務會在升級的模塊中查找tests/子目錄並運行。如今測試會拋出錯誤,在輸出日誌中可看到測試相關的ERROR信息。在爲模塊添加完圖書模型後應該就再也不報錯。

測試業務邏輯

如今咱們應爲業務邏輯添加測試了,理想狀況下每行代碼都應有一個測試用例。在tests/test_book.py文件test_create() 方法再加幾行代碼:

推薦爲每一個需檢查的操做添加一個測試用例,本條測試與上一條類似,先建立一本新書。由於各個測試用例是相互獨立的,用例建立或修改的數據會在測試結束時回滾。而後在建立的記錄上調用測試方法來檢查所使用 ISBN是否被正確驗證。

固然,如今運行測試仍是會失敗,由於所測試的功能還未被實現。

測試安全權限

也能夠對安全權限進行檢測,肯定是否對用戶進行了正確的受權。Odoo 中默認測試由不授權限控制的__system__內部用戶執行。因此咱們應改變執行測試的用戶,來檢測是否授予了正確的安全權限。這經過在self.env中修改執行環境來實現,只需把 user 屬性修改成但願運行測試的用戶便可。修改tests/test_book.py中的setUp方法以下:

第一條命令調用了父類中的setUp代碼,下面一條修改了用於測試的環境self.env爲使用 admin 用戶的新環境。測試代碼的修改到此告一段落。

模型層

既然 Odoo 已經能識別咱們的新模塊了,下面就添加一個簡單的模型。模型描述業務對象,如商機、銷售訂單或合做夥伴(用戶、供應商等)。模型中有一系列屬性,也可定義一些特定業務邏輯。

模型經過 Odoo 模板類派生的 Python 類來實現。它直接與數據庫對象對應,Odoo 在安裝或升級模塊時會自動進行處理。框架中負責這部分的是對象關係映射(ORM -Object Relational Mapping)。

咱們的模塊是一個圖書管理應用,第一個功能就是管理圖書目錄,目前這是咱們惟一須要實現的模型。

建立數據模型

Odoo 開發指南中提到模型的 Python 文件應放在models子目錄中,每一個模型有一個對應文件。所以咱們在library_app模塊主目錄下建立models/library_book.py文件。

ℹ️Odoo 官方編碼指南請見 Odoo 官網。另外一相關的編碼標準文檔爲 OCA 編碼指南

在使用以前,應告知 Python 所需引用的模型目錄,僅需在模塊主__init__.py文件添加:

要引用所建立的 Python 代碼文件,咱們還應添加models/__init__.py文件:

如今咱們能夠在models/library_book.py中加入以下內容:

第一行是 Python 代碼導入語句,讓 Odoo 內核的models和fields對象在這裏可用。緊接着聲明瞭新的模型,它是models.Model派生出的一個類。而後_name 屬性定義了 Odoo 全局對該模型引用的標識符。注意Python 類名 Book 與框架無關,_name 的值纔是模型的標識符。

小貼士:僅有模型名使用點號(.) 來分割關鍵字,其它如模塊、XML 標識符、數據表名等都使用下劃線(_)。

注意下面的行都有縮進,對 Python 不熟悉的朋友要知道這很重要:相同縮進表明同一代碼塊,因此下面的行應採用相同縮進。

_description屬性不是必須的,但爲模型記錄提供了一個用戶友好的名稱,可用做更好的用戶消息。該行以後定義了模型的不一樣字段 ,值得一提的是name和active爲特殊字段名。默認在其它模型中引用模型時,會使用 name 字段做爲記錄的標題。

active 字段用於激活記錄,默認僅 active 記錄會顯示。對於日期模型這很是有用,隱藏掉那些用戶在平常操做中再也不使用的記錄(因歷史緣由仍需保留在數據庫中)。在本項目中,用於標識圖書是否可用。

再來看看其它字段,date_published是一個圖書出版日的日期字段,image 是一個存儲圖書封面的二進制字段。還有一些關聯字段:publisher_id是一個出版公司多對一關聯,author_ids是做者多對多關聯。都是圖書與 partner 模型的關聯,partner 模型內置於 Odoo 框架中,用戶、公司和地址都存儲在這裏。咱們使用它存儲出版商和做者。

字段就是這些,要使代碼修改生效,需更新模塊來觸發數據庫中相應對象的建立。菜單中還沒法訪問這一模型,由於咱們尚未添加。不過能夠經過 Technical 菜單來檢查新建模型。訪問 Settings > Technical > Database Structure > Models(需開啓開發者模式),在列表中搜索library.book,而後點擊查看模型定義:

Odoo 12 開發之建立第一個 Odoo 應用

如查看一切順利,說明模型和字段都被正常建立,若是你看不到這些,嘗試重啓服務升級模型。咱們還能夠看到一些未聲明的字段,這些是 Odoo 自動爲新模型添加的保留字段,這些字段有:

  • id是模型中每條記錄的惟一數字標識符
  • create_date和create_uid分別爲記錄建立時間和建立者
  • display_name爲所使用的記錄提供文本顯示,如其它記錄引用它,它就會被計算並默認使用 name 字段中的文本
  • write_date和write_uid分別表示最後修改時間和修改者
  • __last_update是一個助手字段 ,它不存儲在數據庫,用於作併發檢測

設置訪問權限

在加載服務時,你可能會注意到輸出日誌中有一條警告信息:

The model library.book has no access rules, consider adding one.

提示消息已經很明確了,咱們的新模型沒有訪問規則,因此任何人均可使用。咱們已爲應用添加了安全組,如今就爲模塊受權。

ℹ️在 Odoo 12之前,admin 可自動訪問全部數據模型,它是一個不授權限控制的超級用戶。在 Odoo 12中則再也不如此,須要在新模型中設置 ACL纔對 admin 可見。

添加訪問權限控制

要了解須要哪些信息來爲模型添加權限,可訪問後臺Settings > Technical > Security > Access Rights:

Odoo 12 開發之建立第一個 Odoo 應用

這裏能夠看到一些模型的 ACL(Access Control List),表示容許每一個安全組對記錄的操做。這一信息須要經過模塊中的數據文件提供,而後載入ir.model.access模型。咱們將爲 employee 組添加該模型的全部權限,內部用戶是幾乎全部人隸屬的基本權限組。

ℹ️Odoo 12中的修改
User 表單如今有一個用戶類型,僅在開啓開發者模式時顯示。它容許互斥的幾個選項:內部用戶,portal門戶用戶(外部用戶如客戶)和public公共用戶(網站匿名訪客)。這一修改用於避免把內部用戶放到 portal 或 public 組中一類的錯誤配置,那樣會致使權限的喪失。

權限經過security/ir.model.access.csv文件來實現,添加該文件並加入以下內容:

注:應注意該文件第一行後不要留有空格,不然會致使報錯

文件名必須與要載入的模型對應,第一行爲列名,CSV 文件中有以下列:

  • id是記錄的外部標識符(也稱爲XML ID),需在模塊中惟一
  • name是描述性標題,僅在保證惟一時提供有用信息
  • model_id是賦權模型的外部標識符,模型有ORM自動生成的XML ID,對於library.book,標識符爲model_library_book
  • group_id指明受權的安全組,咱們給前文建立的安全組受權:library_group_user和library_group_manager
  • perm_…字段標記read讀, write寫, create建立, 或unlink刪除權限,咱們授予普通用戶讀權限、管理員全部權限

還應記得在__manifest__.py的 data 屬性中添加對新文件的引用,修改後以下:

老規矩升級模塊讓修改生效,此時警告信息就不見了。咱們經過 admin登陸來檢測權限是否正確,admin 屬於圖書管理員組。

行級權限規則

咱們知道默認 active 標記爲 False 的記錄不可見,但用戶在須要時可以使用過濾器來訪問這些記錄。假設咱們不但願普通圖書用戶訪問無效圖書,可經過記錄規則來實現,即定義過濾器來限制某權限組所能訪問的記錄。這位於Settings > Technical > Security > Record Rules。

記錄規則在ir.rule中定義,和往常同樣咱們選擇一個惟一名稱。還應獲取操做的模型及使用權限限制的域過濾器。域過濾器使用 Odoo 中經常使用的元組列表,在第八章 Odoo 12開發之業務邏輯 – 業務流程的支持將講解域表達式語法。

一般,規則應用於指定安全組,咱們這裏應用的是僱員組。若是沒有指定的安全組,則應用於全局(global 字段自動設爲 True)。全局規則不一樣,它們作的限制非全局規則沒法重載。

要添加記錄規則,需編輯security/library_security.xml文件添加以下代碼:

記錄規則位於<data noupdate=」1″>元素中,表示這些記錄在模型安裝時會被建立,但在模型更新時不會被重寫。這麼作是容許對規則在後面作自定義但避免在執行模型升級時自定義內容丟失。

小貼士:開發過程noupdate=」1″會帶來麻煩,由於要修復規則時模塊更新不會在數據庫中重寫數據。因此在開發時能夠修改成noupdate=」0″來讓數據達到預期結果。

在 groups 字段中,會發現有一個特殊表達式,這是一個帶有特殊語法的one-to-many關聯字段。元組(4, x)表示x應添加到記錄中,此處 x 爲一個標記爲base.group_user的內部用戶組引用。針對多個字段的這種特殊語法在第六章 Odoo 12開發之模型 – 結構化應用數據中探討。

Odoo 12 開發之建立第一個 Odoo 應用

視圖層

視圖層爲用戶界面的描述,視圖用 XML 定義,由網頁客戶端框架生成數據感知的 HTML 視圖。可用菜單項開啓渲染視圖的操做。好比,Users 菜單項處理一個一樣名爲 Users 的操做,而後渲染一系列視圖。有多種可用視圖類型,如 list(因歷史緣由也稱爲 tree)列表視圖和 form表單視圖,以及包含過濾項的右上角搜索框由 search 搜索視圖定義。

Odoo 開發指南寫到定義用戶界面的 XML 文件應放在views/子目錄中。接下咱們來建立圖書應用的用戶界面。下面咱們會逐步改進並更新模塊來使更改生效。可使用–dev=all參數來在開發時頻繁的升級。使用該參數,視圖定義會在 XML 文件中直接讀取,無需升級模塊便可在 Odoo 中即刻生效。

小貼士:若是因 XML 錯誤升級失敗,沒必要驚慌!仔細閱讀輸出日誌的錯誤信息,就能夠找到問題所在。若是以爲麻煩,註釋掉最近編輯的 XML 版塊或刪除__manifest__.py中 該XML 文件,從新更新,服務應該就可正確啓動了。

添加菜單項

如今有了存儲數據的模型,須要添加到用戶界面中。首先要作的就是添加相應菜單項。編輯views/library_menu.xml文件,在 XML 元素中定義菜單項以及執行的操做:

用戶界面,包括菜單項和操做,存儲在數據表中。在安裝或升級插件模塊時,XML文件會將這些定義載入數據庫中的數據文件。以上代碼是一個 Odoo 數據文件,表示兩條添加到 Odoo 的記錄:

  • <act_window>元素定義客戶端窗口操做,它按順序經過啓用列表和表單視圖打開library.book 模型
  • <menuitem>定義一個調用前面定義的action_library_book操做的頂級菜單項

如今再次升級模塊來讓修改生效。而後刷新瀏覽器頁面,就能夠看到Library頂級菜單,幷包含一個子菜單項。點擊該菜單會顯示一個基本列表視圖,記錄可經過一個自動生成的表單視圖進行編輯。點擊 Create 按鈕便可查看:

Odoo 12 開發之建立第一個 Odoo 應用

雖然咱們尚未定義用戶界面視圖,自動生成的列表視圖和表單視圖也可使用,容許咱們立刻編輯數據。

建立表單視圖

全部的視圖都存儲在數據庫ir.ui.view模型中。爲模型添加視圖,咱們在 XML文件中聲明<record>元素來描述視圖,在模塊安裝時 XML 文件會被載入數據庫。

添加views/book_view.xml文件來定義表單視圖:

這個ir.ui.view記錄有三個字段值:name, model和 arch。另外一個重要元素是記錄 id,它定義了一個可在其它記錄中引用的XML ID標識符。這是library.book 模型的視圖,名爲Book Form。這個名稱僅用於提供信息,無需惟一,但應易於分辨所引用的記錄。其實能夠徹底省略 name,這種狀況下會自動按模型名和視圖類型來生成。

最重要的字段是arch,它包含了視圖的定義,在 XML 代碼中咱們作了高亮顯示(博客主題問題沒法顯示)。<form>標籤訂義了視圖類型幷包含視圖結構。

此處<form>中包含了要在表單中顯示的字段。這些字段會自動使用默認的組件,如 date 字段使用日期選擇組件。有時咱們要使用不一樣的組件,如以上代碼中的author_ids使用了顯示標籤列表的組件,image字段使用處理圖片的相應組件。有關視圖元素的詳細說明請見第十章 Odoo 12開發以後臺視圖 – 設計用戶界面

不要忘記在聲明文件的 data 中加入新建文件,不然咱們的模塊將沒法識別到並加載該文件:

要使修改載入 Odoo 數據庫就須要更新模塊。須要從新加載頁面來查看修改效果,能夠再次點擊菜單項或刷新網頁(大多數瀏覽器中快捷鍵爲 F5)。

Odoo 12 開發之建立第一個 Odoo 應用

業務文件表單視圖

上面的部分建立了一個基礎表單視圖,還能夠作一些改進。對於文件模型,Odoo 有一個模擬紙張的展現樣式,表單包含兩個元素:<header>來包含操做按鈕和<sheet>來包含數據字段。能夠修改上一部分的基礎<form>定義爲:

 

添加操做按鈕

表單可帶有執行操做的按鈕。這些按鈕可用於運行窗口操做,如打開另外一個表單或執行模型中定義的 Python 方法。按鈕能夠放在表單的任意位置,但對於文件樣式表單,推薦的位置是<header>中。

咱們的應用會添加圖書 ISBN,和一個用於檢測 ISBN 有效性的按鈕。代碼將放在 Book 模型中,咱們將該方法命名爲button_check_isbn()。雖然還未建立該方法,咱們如今能夠在表單中先添加相應按鈕:

一個按鈕的基本屬性有:

  • string:定義按鈕顯示文本
  • type:執行的操做類型
  • name:操做的標識符
  • class:應用 CSS 樣式的可選屬性,與 HTML 相同

使用組來組織表單

<group>標籤可用於組織表單內容。在<group>元素內加<group>會在外層組中建立一個兩列布局。推薦在group 元素中添加 name 屬性,更易於其它模塊對其進行繼承。咱們使用該標籤來組織內容,修改<sheet>內容以下:

 

完整表單視圖

此時library.book的表單視圖代碼以下:

按鈕還沒法使用,須要先添加業務邏輯。

Odoo 12 開發之建立第一個 Odoo 應用

添加列表視圖和搜索視圖

以列表模式顯示模型須要使用視圖。樹狀視圖能夠按層級顯示,但大多數狀況下僅需顯示爲普通列表。

能夠在book_view.xml文件中添加<tree>視圖:

以上定義了一個含有四列的列表:name, author_ids, publisher_id和 date_published。在該列表的右上角,Odoo 顯示了一個搜索框。搜索的字段和可用過濾器也由視圖定義。一樣還在book_view.xml文件中添加:

<field>元素定義在搜索框中輸入搜索的字段,這裏添加了publisher_id自動提示出版商字段。<filter>元素添加預約義過濾條件,用戶經過點擊來切換,它使用了特殊的語法,在第十章 Odoo 12開發以後臺視圖 – 設計用戶界面中將會進一步介紹。

ℹ️Odoo 12中的修改
<filter>如今要求包含name=」…」屬性,惟一標識每一個過濾器,若是不寫,驗證會失敗,模塊將沒法安裝或升級。

Odoo 12 開發之建立第一個 Odoo 應用

業務邏輯層

業務邏輯層編寫應用的業務規則,如驗證和自動計算。如今咱們來爲按鈕添加邏輯,經過在模型 Python 類中編寫方法來實現。

添加業務邏輯

上文中咱們在 Book表單中添加了一個按鈕,用於檢查 ISBN 是否有效。現代 ISBN 包含13位數字,最後一位是由前12位計算所得的檢查位。咱們無需深刻到算法的細節,這裏是一個實現驗證的 Python 方法。應當在class Book(…)中進行添加:

圖書模型的button_check_isbn()方法應使用該函數來驗證 ISBN 字段中的數字,若是驗證失敗,應向用戶顯示警告信息。

首先要導入 Odoo API庫,添加對應的 import 及 Odoo Warning異常。這須要編輯library_book.py文件修改前兩行爲:

而後仍是在models/library_book.py文件Book 類中加入:

對於記錄的邏輯,咱們使用@api.multi裝飾器。此處 self 表示一個記錄集,而後咱們遍歷每一條記錄。其實@api.multi裝飾器能夠不寫,由於這是模型方法的默認值。這裏保留以示清晰。代碼遍歷全部已選圖書,對於每本書,若是 ISBN 有值,則檢查有效性,若無值,則向用戶拋出一條警告消息。

模型方法無需返回值,但此處需至少返回 True 值。由於不是全部XML-RPC客戶端實現都支持None/Null空值,這種狀況若返回空值則會致使拋出錯誤。此時可更新模塊並再次運行測試,添加–test-enable參數來肯定測試是否經過。也能夠在線測試,進入 Book 表單使用正確和錯誤的 ISBN點擊按鈕進行測試。

Odoo 12 開發之建立第一個 Odoo 應用

網頁和控制器

Odoo 還提供了一個 web 開發框架,可用於開發與後臺應用深度集成的功能。第一步咱們來建立一個顯示有效圖書列表的簡單網頁。在請求http://<my-server>/library/books頁面時會進行響應,因此/library/books是用於實施的 URL。這裏咱們簡短地瞭解下 Odoo 網頁開發,這一話題在第十三章 Odoo 12開發之建立網站前端功能中會深刻探討。

Web控制器是負責渲染網頁的組件。控制器是http.Controller中定義的方法,與URL連接(endpoint)綁定。 訪問 URL 時執行控制器代碼,生成向用戶展現的 HTML。咱們使用 QWeb 模板引擎方便HTML的渲染。

按慣例控制器代碼放在/controllers子目錄中,首先編輯library_app/__init__.py導入控制器模塊目錄:

而後添加library_app/controllers/__init__.py文件來讓目錄可被 Python 導入,並在該文件中添加:

接下來就要建立真實的控制器文件library_app/controllers/main.py,並添加以下代碼:

這裏導入的odoo.http模塊,是提供網頁相關功能的核心組件。http.Controller是須要繼承的類控制器,這裏在主控制器類中使用。咱們選擇的類名和方法並不關聯,@http.route裝飾器纔是重要的部分,它聲明瞭與類方法關聯的 URL 地址,此處爲/books。默認訪問 URL 地址要求客戶登陸,推薦明確指出訪問的受權模式,因此這裏添加了auth=’user’參數。要容許公開訪問,可爲@http.route 添加auth=’public’ 參數。

小貼士:若是使用auth=’public’,控制器代碼中在進行圖書搜索前應使用sudo() 進行提權。這部分在第十三章 Odoo 12開發之建立網站前端功能會進一步討論。

在這個控制器方法中,咱們使用http.request.env獲取環境,使用它可從目錄中獲取有效圖書記錄集。最後一步是使用http.request.render() 來處理 library_app.index_template Qweb 模板並生成輸出 HTML。可經過字典向模板傳值,這裏傳遞了圖書記錄集。

這時若是重啓 Odoo 服務來重載 Python 代碼,並訪問/library/books會獲得一個錯誤日誌:ValueError: External ID not found in the system: library_app.book_list_template。這是由於咱們尚未定義模板。下面就一塊兒來定義模板。

QWeb模板是一個視圖類型,應放在/views子目錄下,咱們來建立views/book_list_template.xml文件:

<template>元素用於聲明 QWeb 模板,它事實上是一個存儲模塊的 base 模型 – ir.ui.view記錄的快捷方式。模板中包含要使用的 HTML,並使用 Qweb 的特定屬性:t-foreach用於遍歷變量 books的每一項,經過控制器的http.request.render()調用來獲取;t-field用於渲染記錄字段的內容。這裏僅簡單地使用 QWeb,更多詳情見第十三章 Odoo 12開發之建立網站前端功能

在模塊的 manifest 中須要聲明該 XML 文件來供加載和使用。進行模塊升級便可經過http://<my-server>:8069/library/books來訪問有效圖書的簡單列表。

Odoo 12 開發之建立第一個 Odoo 應用

注:以上數據爲從 Packt 的 Top 20中添加了當前前3

總結

本文中咱們從0開始建立了一個新模塊,瞭解了模塊中經常使用的元素:模型、三個基礎視圖類型(表單視圖、列表視圖和搜索視圖)、模型方法中的業務邏輯和訪問權限。咱們還學習了訪問權限控制,包括記錄規則以及如何使用網頁控制器和 Qweb 模板來建立網頁。

在學習過程當中,咱們熟悉了模塊開發過程,包含模塊升級和應用服務重啓來使得修改在 Odoo 中生效。不要忘記在添加模塊字段時須要進行更新操做。修改含聲明在內的 Python 文件須要重啓服務。修改XML或CSV文件需進行更新,一旦不肯定,同時進行重啓服務和升級模塊操做。

咱們已經學習建立 Odoo 應用的基本元素和步驟,但大多數狀況下,咱們的模塊都是對已有應用添加功能來進行擴展,咱們將在下一篇文章中一塊兒學習。

☞☞☞第四章 Odoo 12 開發之模塊繼承

學霸專區

  1. library-app是正確的模塊名嗎?
  2. 模塊是否應爲其中全部的模型定義訪問控制列表(ACL)?
  3. 是否可讓某些用戶僅訪問一個模型記錄的子集?
  4. 關聯字段和其它字段類型有什麼區別?
  5. Odoo 應用中使用的主要視圖組件有哪些?
  6. 後臺視圖如何定義?
  7. Odoo 應用中的業務邏輯應在哪裏實現?
  8. Odoo 使用的網頁模板引擎是什麼?
相關文章
相關標籤/搜索