全書完整目錄請見:Odoo 12開發(fā)者指南(Cookbook)第三版
本章中漠秋,我們將講解如下內容:
- 創(chuàng)建和安裝一個新的插件模塊
- 完成插件模塊的聲明
- 組織插件模塊文件結構
- 添加模型
- 添加菜單項和視圖
- 添加訪問權限
- 使用腳手架命令來創(chuàng)建模塊
技術準備
本章中,我們將預設你已安裝了Odoo并且按照第一章 安裝Odoo開發(fā)環(huán)境進行的操作舞丛。你還應熟悉第二章 管理Odoo服務器實例中所描述的查找和安裝附加的插件模塊。本章中所使用的代碼可以從如下GitHub倉庫中進行下載:https://github.com/alanhou/odoo12-cookbook/tree/master/Chapter04/my_library溉委。
代碼實時操作的視頻請見:http://t.cn/E9PzDbm
引言
現(xiàn)在我們已經有了開發(fā)環(huán)境并且知道如何管理Odoo實例和數(shù)據(jù)庫衡载,可以學習如何創(chuàng)建Odoo插件模塊了。
這里我們的主要目標是理解一個插件模塊的結構是什么樣的以及對其進行補充的典型增量工作流矮嫉。本章中各節(jié)所討論的各種組件會在后續(xù)章節(jié)中進行擴充講解。
Odoo的插件模塊是什么牍疏?
除框架代碼以外蠢笋,Odoo的所有基礎代碼都以模塊的形式組合在一起。這些模塊可以隨時從數(shù)據(jù)庫中安裝或卸載鳞陨。這些模塊有兩大目的昨寞。要么你可以添加新應用/業(yè)務邏輯,要么你可以修改已有應用厦滤。簡言之援岩,Odoo中的一切都始于模塊也終于模塊。
Odoo由不同規(guī)模的公司所使用掏导,每個公司都有不同的業(yè)務流和要求享怀。處理這一問題,Odoo將應用的功能拆分到了不同的模塊中趟咆。這些模塊可按需在數(shù)據(jù)庫中進行加載添瓷。基本上值纱,用戶可以在任何時間點啟用/禁用這些功能鳞贷。因此,相同的軟件可以按不同的要求進行調整虐唠。查看下面Odoo模塊的截屏搀愧;該列中第一個模塊是主應用,其它的模塊為該應用添加功能而設計。讓模塊列表按應用分類進行分組咱筛,進入Apps菜單并對Category應用分組:
如果你計劃在Odoo中開發(fā)新應用搓幌,應為不同功能設置邊界。這有助于將你的應用切分為不同的插件模塊眷蚓。既然你已經知道了Odoo中插件模塊的用途鼻种,我們可以開始構建自己的插件模塊了反番。
創(chuàng)建和安裝一個新的插件模塊
這一節(jié)中沙热,我們將新建一個模塊,讓其在我們的Odoo實例中可用并安裝它罢缸。
準備工作
我們需要準備好一個Odoo實例來開始我們的開發(fā)篙贸。
如果我按照第一章 安裝Odoo開發(fā)環(huán)境的從源碼輕松安裝Odoo一節(jié)進行操作的話,Odoo應該在~/odoo-dev/odoo下枫疆。為方便講解爵川,我們假定Odoo安裝在該路徑下,但是你可以使用其它你自己偏好的路徑息楔。
我們還需要一個位置來安裝自己的Odoo模塊寝贡。就本節(jié)而言,我們將使用odoo的同級目錄:~/odoo-dev/local-addon值依。
如何操作...
本章的示例中圃泡,我們將創(chuàng)建一個小型的插件模塊來管理圖書館中的一系列圖書。
如下步驟將創(chuàng)建并安裝一個新的插件模塊:
- 進入到工作目錄即你要操作并放置新建的自定義模塊的插件目錄中:
$ cd ~/odoo-dev
$ mkdir local-addons
- 為新模塊選擇一個技術名稱并使用該名稱作為模塊名創(chuàng)建目錄愿险。本例中颇蜡,我們將使用my_library:
$ mkdir local-addons/my_library
> ??模塊的技術名稱必須是有效的Python標識符,需以字母開頭辆亏,僅包含字母风秤、數(shù)字和下劃線。建議在模塊名稱中只使用小寫字母扮叨。
- 通過添加init.py文件來讓Python模塊可導入:
$ touch local-addons/my_library/__init__.py
- 為Odoo添加一個最小化的模塊聲明來將其作為一個插件模塊缤弦。創(chuàng)建manifest.py 文件并添加如下行:
{'name': 'My Library'}
- 啟動你的Odoo實例,將你的插件目錄添加到插件路徑中:
$ odoo/odoo-bin --addons-path=odoo/addon/,local-addons/
> ??如果在該Odoo命令中添加了 --save 選項彻磁,插件路徑會被保存到配置文件中甸鸟。下次你啟動服務時,如果沒有提供插件路徑選項的話兵迅,就會使用它抢韭。
- 讓這個新模塊在Odoo中可用;使用管理員登錄Odoo恍箭,啟動開發(fā)者模式刻恭,然后在Apps頂級菜單中選擇Update Apps List。現(xiàn)在Odoo就識別到了我們的模塊了。
- 選擇頂部的Apps菜單鳍贾,在右上方的搜索欄中鞍匾,刪除默認的應用過濾器并搜索my_library,點擊它的Install按鈕骑科,就完成了安裝橡淑。
運行原理...
Odoo模塊是一個包含代碼文件及其它資源的目錄。所使用的目錄名為模塊的技術名稱咆爽。模塊聲明中的 name 鍵對應其標題梁棠。
manifest.py文件是模塊的聲明。它包含一個帶有模塊元數(shù)據(jù)的Python字典斗埂,有分類符糊、版本、它所依賴的模塊以及一系列它將要加載的數(shù)據(jù)文件呛凶。在這一節(jié)中男娄,我們使用了最簡化的聲明文件,但在真實的模塊中漾稀,我們將使用其它的重要爭名模闲。這將在下一節(jié)完成插件模塊的聲明是進行討論。
模塊目錄必須是Python可導入的崭捍,因此即便目錄為空也要添加一個init.py 文件尸折。要載入一個模塊,Odoo模塊將會導入它缕贡。這會導致init.py文件中的代碼被執(zhí)行翁授,它作為運行該模塊Python代碼的一個入口。因此晾咪,它通常會包含加載模塊Python文件及子模塊的一些重要聲明語句收擦。
已識別模塊可通過命令行使用--init或-i選項直接安裝。這一模塊列表在提供插件路徑新建數(shù)據(jù)庫時獲取到的模塊進行初始化設置谍倦∪福可通過Update Module List菜單更新已有數(shù)據(jù)庫。
完成插件模塊的聲明
聲明文件對于Odoo模塊非常重要昼蛀。它包含插件模塊重要的元數(shù)據(jù)并聲明了應加載的數(shù)據(jù)文件宴猾。
準備工作
我們應當有一個包含manifest.py聲明文件的模塊來進行操作。你可能要按前一節(jié)的步驟來提供一個可以操作的模塊叼旋。
如何操作...
我們?yōu)檫@個插件模塊添加一個聲明文件和一個圖標:
- 以最相關的鍵名創(chuàng)建一個聲明文件仇哆,編輯模塊的manifest.py文件至內容如下:
{
'name': "My library",
'summary': "Manage books easily",
'description': """Long description""",
'author': "Your name",
'website': "http://www.example.com",
'category': 'Uncategorized',
'version': '12.0.1',
'depends': ['base'],
'data': ['views.xml'],
'demo': ['demo.xml'],
}
- 為該模塊添加一個圖標,需選擇一個PNG圖像來供使用并將其拷貝至static/description/icon.png
運行原理...
聲明文件中的內容是一個常規(guī)的Python字典夫植,包含鍵和值讹剔。我們的示例聲明中包含了大部分相關的鍵名:
- name:這是該模塊的標題油讯。
- summary:這是一個單行描述的副標題。
- description:這是一個以普通文本或重構文本(RST)格式編寫的長描述延欠。通常放在三個引號中陌兑,Python中使用三個引號來界定多行文本。RST的快速入門指南請見http://docutils.sourceforge.net/docs/user/rst/quickstart.html由捎。
- author:是一個作者姓名的字符串兔综。如果有多個作者的話,一般使用逗號來進行分隔狞玛,但注意它仍應是一個字符串软驰,而非Python列表。
- website:這個 URL 可供人們訪問來了解模塊或作者的更多信息为居。
- category:這用于在網(wǎng)絡上組織模塊碌宴。標準的分類名稱列表請見https://github.com/odoo/odoo/blob/12.0/odoo/addons/base/data/ir_module_category_data.xml杀狡。但也可以定義這些名稱以外的分類名稱蒙畴。
- version:這是該模塊的版本號∥叵螅可由Odoo應用商店用于檢測已安裝模塊的新版本膳凝。如果版本號沒有以Odoo目標版本號(如12.0)開始,會進行自動添加恭陡。但是蹬音,如果你顯式的聲明Odoo目標版本號信息量會充足,比如用12.0.1.0.0或12.0.1.0來替代1.0.0或1.0休玩。
- depends:這是該模塊所直接依賴的模塊技術名稱列表著淆。如果你的模塊不依賴于任何其它插件模塊,那么應至少添加一個base模塊拴疤。別忘記包含這個模塊所引用的XML ID永部、視圖或模塊的定義模塊。那樣會確保它們以正確的順序進行加載呐矾,避免難以調試的錯誤苔埋。
- data:這是在模塊安裝或升級時需加載數(shù)據(jù)文件的相對路徑列表。這些路徑相對于模塊的根目錄蜒犯。通常组橄,這些是XML和CSV文件,但也可以使用YAML格式的數(shù)據(jù)文件罚随。這些內容會在第七章 模塊數(shù)據(jù)中深入討論玉工。
- demo:這是加載演示數(shù)據(jù)的文件的相對路徑列表。僅在創(chuàng)建數(shù)據(jù)庫時啟用了Demo Data標記時都會進行加載淘菩。
模塊圖標使用的圖像是位于static/description/icon.png的一個PNG文件遵班。
小貼士:Odoo的大版本一般會有較大的變化,因此如不進行轉化或遷移操作的話,一個大版本中構建的模塊不大可能與下一個版本進行兼容费奸。因此弥激,在安裝模塊前確定Odoo的目標版本號就非常的重要了。
擴展內容
也可以使用一個單獨的描述文件來替代模塊聲明中的長描述愿阐。自8.0版起微服,可通過后綴名為 .txt、.rst或.md(Markdown)的README文件來進行替換缨历。此外以蕴,可在模塊中包含一個description/index.html文件。
這個HTML描述會覆蓋掉聲明文件中所定義的描述辛孵。
還有一些常用的其它鍵名:
- licence:默認值為LGPL-3丛肮。這一標識符用于模塊對外使用的證書。其它可用的證書有AGPL-3魄缚、Odoo自有證書v1.0(多用于付費應用)以及其它OSI核準的證書宝与。
- application:如果為True,模塊作為應用列出冶匹。通常這用于一個功能區(qū)的中央模塊习劫。
- auto_install:若為True,表示這是一個膠水模塊嚼隘,在它所有的依賴模塊安裝后會被自動安裝诽里。
- installable:若為True(默認值),表示該模塊可以進行安裝飞蛹。
- external_dependencies:有些Odoo模塊內部使用了Python/bin庫谤狡。如果你的模塊使用了這些庫,需要在這里進行添加卧檐。如果列出的模塊在你的主機上沒有安裝的話則會停止該模塊的安裝墓懂。
- {pre_init, post_init, uninstall}_hook:這是在安裝/卸載時調用的Python函數(shù)鉤子。更多詳細示例泄隔,請見第九章 高級服務端開發(fā)技巧拒贱。
組織插件模塊文件結構
一個插件模塊包含代碼及其它資源文件,如XML文件和圖像佛嬉。大多數(shù)這些文件逻澳,我們都可以自由選擇其在插件目錄中的存放位置。
但是暖呕,Odoo使用了一些模塊結構的慣例斜做,建議遵循這一慣例。
準備工作
我們應當有一個插件模塊目錄湾揽,其中僅包含init.py和manifest.py文件瓤逼。本節(jié)中笼吟,我們假定目錄為local-addons/my_library。
如何操作...
執(zhí)行如下步驟來為該插件模塊創(chuàng)建基本結構:
- 為代碼文件創(chuàng)建目錄:
$ cd local-addons/my_library
$ mkdir models
$ touch models/__init__.py
$ mkdir controllers
$ touch controllers/__init__.py
$ mkdir views
$ mkdir security
$ mkdir data
$ mkdir demo
$ mkdir i18n
- 編輯模塊的頂級 init.py文件霸旗,這樣子目錄中的代碼會被加載到:
from . import models
from . import controllers
這會給我們一個包含最常用目錄的入手結構贷帮,類似下面這樣:
.
├── __init__.py
├── __manifest__.py
├── controllers
│ └── __init__.py
├── data
├── demo
├── i18n
├── models
│ └── __init__.py
├── static
│ └── description
│ └── icon.png
└── views
運行原理...
為大家普及一下背景,Odoo插件模塊可以有三種類型文件:
- Python代碼由 init.py加載诱告,通過該文件導入.py文件及代碼子目錄撵枢。子目錄中包含的Python代碼,再由其內部的init.py導入精居。
- 模塊聲明文件manifest.py中data和demo鍵名所聲明供加載的數(shù)據(jù)文件通常是用戶界面锄禽、fixture數(shù)據(jù)和演示數(shù)據(jù)中會使用到的XML和CSV文件。還可使用YAML文件靴姿,可以包含一些模塊加載時運行的過程指令沃但,例如,通過程序生成或更新記錄而非在XML文件中加入數(shù)據(jù)佛吓。
- 網(wǎng)頁資源宵晚,如JavaScript代碼和庫、CSS辈毯、SASS和QWeb/HTML模板坝疼。這些文件用于在 UI 元素中構建UI組成部分及管理用戶動作搜贤。它們通過繼承主模板的XML文件來進行聲明谆沃,用于為網(wǎng)頁客戶端或網(wǎng)站頁面添加這些資源。
插件文件以如下目錄進行組織:
- models/包含后端代碼文件仪芒,用于創(chuàng)建模型及其業(yè)務邏輯唁影。推薦每個模型一個文件并使用與模型相同的名稱,例如 library.book模型的對應文件為library_book.py掂名。這些在第五章 應用模型中會進行深入講解据沈。
- views/包含用于用戶界面的XML文件,包含動作饺蔑、表單锌介、列表等等。類似于模型猾警,建議每個模型一個文件孔祸。網(wǎng)站模塊的文件名通常以_template后綴進行結尾。后端視圖在第十章 后端視圖中講解发皿,網(wǎng)站視圖在第十五章 CMS網(wǎng)站開發(fā)中進行講解崔慧。
- data/包含模塊初始數(shù)據(jù)的其它數(shù)據(jù)文件。數(shù)據(jù)文件在第七章 模塊數(shù)據(jù)中進行講解穴墅。
- demo/包含帶演示數(shù)據(jù)的數(shù)據(jù)文件惶室,對于測試温自、培訓或模塊評測都非常有用。
- Odoo會在i18n/中查找.pot及.po翻譯文件皇钞。更多詳情參見第十二章 國際化悼泌。這些文件無需在聲明文件中提及。
- security/包含定義訪問控制列表的數(shù)據(jù)文件夹界,通常是一個ir.model.access.csv文件券躁,也可以是一個XML文件,用于定義權限組及行級權限的記錄規(guī)則掉盅。參見第十一章 權限安全來獲取更多內容也拜。
- controllers/包含網(wǎng)站控制器的代碼文件,用于為模塊提供各種功能趾痘。網(wǎng)頁控制器在第十四章 網(wǎng)頁服務端開發(fā)中進行講解慢哈。
- static/用于放置所有的網(wǎng)頁資源。和其它目錄不同永票,該目錄名不只是一種慣例卵贱。這一目錄中的文件無需用戶登錄即可對外提供訪問。該目錄多包含JavaScript侣集、樣式表键俱、圖像等文件。它們無需在模塊聲明文件中進行提及世分,但需要在網(wǎng)頁模板中引用编振。這會在第十五章 CMS網(wǎng)站開發(fā)中進行討論候衍。
小貼士:在向模塊添加新文件時饭豹,不要忘記在manifest.py(數(shù)據(jù)文件)或init.py(代碼文件)文件中進行聲明,否則會忽略這些文件而不進行加載渊额。
添加模型
數(shù)據(jù)結構中定義的模型會用于我們的業(yè)務應用瓢阴。這一節(jié)向讀者展示如何為模塊添加基本模型。
在我們的示例中荣恐,希望對圖書館的書籍進行管理。那么叠穆,我們需要創(chuàng)建一個代表書籍的模型。每本書包含書名及一名或多名作者痹束。
準備工作
我們需要有一個模塊來進行操作。如果你按照本章第一節(jié)創(chuàng)建和安裝一個新的插件模塊操作的話屎媳,則會有一個名為my_library的空模塊夺溢。我們將使用它來做進一步講解风响。
如何操作...
要添加新模型,我們需要添加一個Python文件來描述它状勤,然后升級插件模塊(如未安裝則執(zhí)行安裝)双泪。以下使用的路徑為我們的插件模塊目錄中的相對路徑(例如持搜,~/odoo-dev/local-addons/my_library/):
- 為模塊添加一個 Python 文件models/library_book.py,代碼如下:
from odoo import models, fields
class LibraryBook(models.Model):
_name = 'library.book'
name = fields.Char('Title', required=True)
date_release = fields.Date('Release Date')
author_ids = fields.Many2many(
'res.partner',
string='Authors'
)
- 在模塊中添加一個Python初始化文件models/init.py來加載代碼焙矛,內容如下:
from . import library_book
- 編輯模塊的Python初始化文件來在模塊中加載models/目錄:
from . import models
- 從命令行或用戶界面中的Apps菜單中升級該Odoo模塊葫盼。如果你在升級模塊時仔細查看服務日志的話,會看到如下行:
odoo.modules.registry: module my_library: creating or updating database table
然后村斟,就可以在我們的Odoo實例中使用這一新的library.book模型了贫导。有兩種方式來查看我們的模型是否在數(shù)據(jù)庫中進行了添加。
第一種方式是你可以在用戶界面中進行查看蟆盹。激活開發(fā)者工具孩灯,然后打開菜單Settings>Technical>Database Structure>Models。然后在那里搜索library.book模型逾滥。
第二種方式是查看PostgreSQL數(shù)據(jù)庫中的表數(shù)據(jù)峰档。你可以在數(shù)據(jù)庫中搜索library_book數(shù)據(jù)表。在下面的代碼示例中匣距,我們使用了test-12.0作為數(shù)據(jù)庫面哥。但是你可以修改為你自己的數(shù)據(jù)庫名:
$ psql test-12.0
test-12.0# \d library_book;
運行原理...
第1步中我們在模塊中創(chuàng)建一個了一個Python文件。
Odoo框架有著其自己的ORM框架毅待。這一ORM對PostgreSQL數(shù)據(jù)庫進行了抽象。通過繼承Odoo Python類Model归榕,我們可以創(chuàng)建自己的模型(數(shù)據(jù)表)尸红。在定義新模型時,也將其加入到了中央模型倉庫中刹泄。這讓其它模塊在之后對其進行修改變得更為容易外里。
模型有一些以下劃線為前綴的通用屬性。最重要的一個是_name特石,它提供了一個唯一內部標識符來在Odoo實例中進行使用盅蝗。ORM會根據(jù)這個屬性來生成數(shù)據(jù)表。本節(jié)中姆蘸,我們使用了_name = 'library.book'芙委」嗦拢基于這一屬性侧啼,該ORM框架會創(chuàng)建一個名為library_book的新數(shù)據(jù)表痊乾。注意ORM在創(chuàng)建新表的名稱時會通過將_name屬性中的. 替換為 _ 符喝。
模型字段以類型屬性的方式進行定義协饲。我們首先以Char類型定義了name字段茉稠。模型中有這一字段會非常方便而线,因為默認在其它模型中引用該模型時膀篮,它會用作記錄描述誓竿。
我們還使用了一個關聯(lián)字段的示例author_ids筷屡。這在圖書和其作者之前建立了一個多對多的關聯(lián)毙死。一本書可以有多個作者扼倘,而每個作者也可以編寫多本書再菊。
有關模型有很多可以討論的地方袄简,我們將在第五章 應用模型中進行深度講解绿语。
接下來吕粹,我們必須讓我們的模塊可以識別到這一新的Python文件匹耕。這通過init.py文件來實現(xiàn)稳其。因為將代碼放在了models/子目錄內既鞠,我們需要前述的init.py 文件來導入該目錄嘱蛋,其中又應包含另一個init.py文件龄恋,在其中導入那里的每一個代碼文件(本例中只有一個文件)郭毕。
對Odoo模型的修改通過升級該模型來啟用铣卡。Odoo服務會處理由模型類到數(shù)據(jù)庫結構變化的轉換。
雖然此處沒有提供示例敞峭,業(yè)務邏輯也可以在這些Python文件中進行添加旋讹,或通過對模型類添加新的方法,或繼承已有方法害驹,如create() 或 write()宛官。這在第六章 基本服務端部署中進行討論底洗。
添加菜單項和視圖
在有了我們的數(shù)據(jù)結構所需的模型之后亥揖,我們希望用戶可以通過用戶界面與它們進行交互费变。本節(jié)基于上一節(jié)的圖書模型進行創(chuàng)建挚歧,添加一個菜單項來顯示一個包含列表和表單視圖的用戶界面昼激。
準備工作
需要有實現(xiàn)library.book模型的插件模塊橙困,這在上一節(jié)中已經提供到凡傅。使用的路徑為相對插件模塊所處位置的相對路徑(如~/odoo-dev/local-addons/my_library/)夏跷。
如何操作...
要添加一個視圖槽华,我們將添加一個XML文件猫态,其中包含對于模塊的定義勇凭。因其是一個新模型虾标,我們還應添加一個菜單選項來讓用戶可以訪問它璧函。
注意下述步驟的順序也是很重要的柳譬,因為其它的一些會引用到在之前步驟中定義的ID:
- 創(chuàng)建一個XML文件views/library_book.xml來添加描述用戶界面的數(shù)據(jù)記錄:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Data records go here -->
</odoo>
- 在插件模塊聲明文件manifest.py中添加新的數(shù)據(jù)文件美澳,通過views/library_book.xml來進行添加:
{
'name': "My Library",
'summary': "Manage books easily",
'depends': ['base'],
'data': ['views/library_book.xml'],
}
- 在library_book.xml文件中添加打開視圖的動作:
<record id='library_book_action'
model = 'ir.actions.act_window'>
<field name="name">Library Books</field>
<field name="res_model">library.book</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
- 在library_book.xml文件中添加菜單項制跟,讓其對用戶可見:
<menuitem name="My Library" id="libray_base_menu" />
<menuitem name="Books" id="library_book_menu"
parent="libray_base_menu" action="library_book_action" />
- 在library_book.xml文件中添加一個自定義表單視圖:
<field name="name">Library Book Form</field>
<field name="model">library.book</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="name" />
<field name="author_ids" widget="many2many_tags" />
</group>
<group>
<field name="date_release" />
</group>
</group>
</form>
</field>
</record>
- 在library_book.xml文件中添加自定義樹狀(列表)視圖:
<field name="name">Libray Book List</field>
<field name="model">library.book</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="date_release" />
</tree>
</field>
</record>
- 在library_book.xml文件中添加自定義搜索選項:
<field name="name">Library Book Search</field>
<field name="model">library.book</field>
<field name="arch" type="xml">
<search>
<field name="name" />
<field name="author_ids" />
<filter string="No Author"
name="withou_author"
domain="[{'author_ids', '=', False}]" />
</search>
</field>
</record>
從版本號12開始读串, admin 用戶必須要獲取相應的訪問權限才能在用戶界面中訪問我們的模型恢暖。在沒有賦予相應的訪問權限時杰捂,Odoo是不會顯示你的菜單和視圖的在下一節(jié)中,我們將為我們的模型添加訪問權限挨队,在那之后你才可以通過admin用戶來查看這些菜單和視圖盛垦。
以超級用戶訪問 Odoo
通過將admin轉換為超級用戶superuser情臭,你就可以不受訪問權限的限制赌蔑,因此無需授予訪問權限即可訪問所有菜單和視圖娃惯。要將admin用戶轉換為superuser趾浅,先激活開發(fā)者模式皿哨。然后在開發(fā)者工具選項中证膨,點擊Become super user選項央勒。
以下截圖供您參考:
在成為超級用戶之后稳吮,你的菜單會顯示一個條狀背景,如下圖所示:
這時如果你試著升級模塊灶似,則會看到一個新的菜單選項(可能會需要刷新瀏覽器)酪惭。點擊Books菜單會打開圖書模型的列表視圖撞蚕,如下圖所示:
運行原理...
在底層中甥厦,用戶界面由存儲在特定模型中的記錄所定義刀疙。前兩步中創(chuàng)建了一個空的XML文件來定義待加載的記錄谦秧,然后將它們添加到模型的數(shù)據(jù)文件列表中來供安裝。
數(shù)據(jù)文件可以放在該模型目錄中的任意位置锥累,但按照習慣用戶界面的數(shù)據(jù)文件在views/子目錄中定義桶略。通常际歼,這些文件的名稱是基于模型的名稱的鹅心。本例中旭愧,我們?yōu)閘ibrary.book模型創(chuàng)建用戶界面虐秋,因此我們創(chuàng)建了views/library_book.xml文件客给。
下一步是定義在客戶端主區(qū)域用戶界面中顯示的窗口動作靶剑。該動作有一個由 res_model,定義的目標模型桩引,name屬性用于在用戶打開動作時向用戶所顯示的標題坑匠。這些都是基本屬性厘灼。窗口動作還支持其它屬性,讓我們對視圖渲染方式擁有更多的控制舰讹,比如顯示什么視圖月匣,為可用的記錄添加過濾器或設置默認值。這些會在第十章 后端視圖中進行討論素标。
通常糯钙,數(shù)據(jù)記錄使用<record>標簽定義退腥,在本例中我們?yōu)閕r.actions.act_window模型創(chuàng)建了一條記錄狡刘。這會創(chuàng)建窗口動作困鸥。
類似地疾就,菜單項存儲在ir.ui.menu模型中猬腰,我們可以使用<record>標簽來進行創(chuàng)建。但是在Odoo中有一個名為<menuitem>的快捷標簽盒延,因此我們在本例中進行了使用添寺。
以下是菜單項的主要屬性:
- name:這是要顯示的菜單項文本计露。
- action:這是要執(zhí)行的動作的標識符票罐。我們使用前一步中所創(chuàng)建的窗口動作ID胶坠。
- sequence:這用于設置同級菜單項的顯示順序乡数。
- parent:這是父級菜單項的標識符闻牡。本例中的菜單項沒有父級玖翅,即它會顯示在頂級菜單中金度。
至此猜极,我們還沒有在模型中定義任何視圖跟伏。但是受扳,如果這時你升級了該模型勘高,Odoo會自動地實時為你創(chuàng)建視圖相满×⒚溃可是建蹄,我們一定會想要控制視圖的展示內容洞慎,因此劲腿,在接下來的兩步中創(chuàng)建了一個表單視圖和一個樹狀視圖挥吵。
這兩個視圖通過 ir.ui.view 模型上的一條記錄進行定義忽匈。我們所使用的屬性如下:
-
name:這是標識視圖的標題丹允。在Odoo的源碼中雕蔽,你會發(fā)現(xiàn)這里重復使用了XML ID,但是你完全可以添加一個更易于閱讀的名稱作為標題碳默。
小貼士:如果省略了name字段嘱根,Odoo會使用模型名稱及視圖類型來生成一個该抒。對于新模型的標準視圖這完全沒有問題。在繼承視圖時建議使用一個更具說明性的名稱顶燕,因為這會讓你在Odoo用戶界面上查找具體視圖時更為方便凑保。
model:這是目標模型的內部標識符,和_name屬性中的所定義的名稱一致涌攻。
arch:這是視圖結構欧引,實際定義結構的地方。這里不同類型的視圖會有不同恳谎。
表單視圖在頂級<form>元素中定義芝此,它的畫布是一個兩列網(wǎng)格。在表單內婚苹,<group>元素用于在垂直方向上編排字段谭企。兩個組會生成包含<field>元素所定義字段的兩個列糟港。字段根據(jù)數(shù)據(jù)類型使用其默認組件剥汤,但可以使用widget屬性來指定所要使用的組件暮芭。
樹狀視圖要簡單些,它們以包含用于各列中顯示的<field>元素的頂級<tree>元素定義聚假。
最后,我們添加了搜索視圖來在右上角的搜索框中擴展搜索選項。在頂級的<search>標簽中,可以包含<field>和<filter>元素。字段元素是在搜索視圖中可用于搜索的其它字段。過濾器元素為可通過點擊激活的預置過濾條件。這些話題會在第十章 后端視圖中進行討論。
添加訪問權限
在添加新的數(shù)據(jù)模型時,你需要定義誰可以創(chuàng)建、讀取蒲赂、更新和刪除記錄。在創(chuàng)建一個全新的應用時,這可能還包含新的用戶組的定義。因此迎瞧,如果用戶沒有訪問權限的話足绅,Odoo則不會該顯示菜單和視圖。在上一節(jié)中,我們將admin用戶轉換為超級用戶來訪問這個菜單。在學完本節(jié)后,你就可以直接以admin用戶來訪問我們圖書模塊的菜單和視圖了杨凑。
這一節(jié)使用上一節(jié)中的定義的圖書模型伺帘,會定義一個用戶安全組來控制誰能夠訪問或修改書籍記錄帝洪。
準備工作
我們會需要上一節(jié)中實現(xiàn)了library.book模型的插件模塊,因為在這一節(jié)我們會為其添加權限規(guī)則常空。使用的是插件模塊所在位置(例如~/odoo-dev/local-addons/my_library/)的相對路徑。
如何操作...
我們要在本節(jié)中添加的安全規(guī)則如下:
- 所有人均可閱讀圖書記錄
- 名為Librarians的新用戶組擁有創(chuàng)建盗棵、閱讀狱庇、更新和刪除書籍記錄的權限
要進行實現(xiàn)驻债,我們需要執(zhí)行如下步驟:
- 創(chuàng)建一個名為security/groups.xml的文件并添加如下內容:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="group_librarian" model="res.groups">
<field name="name">Librarians</field>
<field name="users" eval="[(4, ref('base.user_admin'))]" />
</record>
</odoo>
- 添加一個名為security/ir.model.access.csv的文件并加入如下內容:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
acl_book,library.book_default,model_library_book,,1,0,0,0
acl_book_librarian,library.book_librarian,model_library_book,group_librarian,1,1,1,1
- 在manifest.py中添加這兩個數(shù)據(jù)文件:
# ...
'data': [
'security/groups.xml',
'security/ir.model.access.csv',
'views/library_book.xml'
],
# ...
在實例中更新插件后即可使用新定義的權限規(guī)則了。
運行原理...
我們提供了兩個新數(shù)據(jù)文件并添加到了插件模塊的聲明文件中钧敞,這樣安裝或升級該模塊時會在數(shù)據(jù)庫中加載它們:
- security/groups.xml通過創(chuàng)建一條res.groups記錄來定義一個新權限組凤巨。我們通過admin用戶的引用ID base.user_admin為其授予了Librarians的權限谎砾,這樣admin用戶將擁有l(wèi)ibrary.book模型的權限妆毕。
- ir.model.access.csv通過組來關聯(lián)模型的權限关斜。第一行group_id:id列為空二驰,表示該規(guī)則適用于所有人棘捣。最后一行授予了我們剛剛創(chuàng)建的組的成員所有權限:
小貼士:聲明文件中data版塊內文件的順序非常重要呜投,創(chuàng)建權限組的文件必須要在列出安全權限的文件之前加載男图,因為安全權限的定義依賴于組的存在乃戈。因為視圖可具體到權限組习贫,我們推薦將組的定義文件放在該列表中會更為保險蜡歹。
其它內容
- 有關權限本書有單獨的一章父款。更多有關權限的內容,參見第十一章 權限安全蛛壳。
使用腳手架命令來創(chuàng)建模塊
在新建 Odoo 模塊時砌函,需要設置一些范本代碼劣像。為幫助大家快速新建模塊,Odoo提供了scaffold(腳手架)命令。
本節(jié)向你展示如何使用scaffold命令新建一個模塊睛驳,它會創(chuàng)建一個目錄和文件結構來供使用辆苔。
準備工作
我們將在一個自定義模塊目錄中新建一個插件模塊,因此需要已安裝Odoo并且給自定模塊一個目錄扼劈。假定Odoo安裝的位置為/odoo-dev/odoo,我們的自定義模塊會放置在/odoo-dev/local-addons目錄中菲驴。
如何操作...
我們將使用scaffold命令來創(chuàng)建樣例代碼荐吵。按照給定的步驟來使用scaffold命令新建一個模塊:
- 更改工作目錄到想要放置模塊的地方。它可以是你所選擇的任意目錄赊瞬,但需要在一個插件路徑中才可進行使用先煎。按照我們在前面小節(jié)中所選擇的目錄,應該是這樣的:
$ cd ~/odoo-dev/local-addons
- 為這個新模塊選擇一個技術名稱巧涧,并使用scaffold命令來創(chuàng)建它薯蝎。本例中,我們選擇的是my_module:
$ ~/odoo-dev/odoo/odoo-bin scaffold my_module
- 編輯默認聲明文件manifest.py并修改相應的值谤绳。你一定會想要修改name鍵中的模塊標題占锯。
以下是生成的插件模塊的結構:
$ tree my_module/
my_module/
├── controllers
│ ├── controllers.py
│ └── __init__.py
├── demo
│ └── demo.xml
├── __init__.py
├── __manifest__.py
├── models
│ ├── __init__.py
│ └── models.py
├── security
│ └── ir.model.access.csv
└── views
├── templates.xml
└── views.xml
5 directories, 10 files
現(xiàn)在你應編輯各個生成的文件來適應你對新模塊的需求。
運行原理...
scaffold命令創(chuàng)建基于一個模板的新模塊結構缩筛。
默認消略,這個新模塊在當前工作目錄中進行創(chuàng)建,但我們也可以指定一個目錄來創(chuàng)建該模塊瞎抛,將其作為一個額外的參數(shù)進行傳遞艺演。
參考如下示例:
$ ~/odoo-dev/odoo/odoo-bin scaffold my_module ~/odoo-dev/local-addons
此處使用了一個默認模板,但也可以為網(wǎng)站主題編寫的主題模板桐臊√コ罚可以使用 -t選項來選擇一個指定的模板。我們也可以使用包含模板的一個目錄來作為路徑断凶。
這表示我們可以通過scaffold命令來使用我們自己的模板伤提。內置的主題可作為一個向導,可以在./odoo/cli/templates這個Odoo子目錄中找到懒浮。我們可以用類似下面的命令來使用我們自己的模板:
$ ~/odoo-dev/odoo/odoo-bin scaffold -t path/to/template my_module