Odoo 12開發(fā)者指南第四章 創(chuàng)建Odoo插件模塊

全書完整目錄請見:Odoo 12開發(fā)者指南(Cookbook)第三版

本章中,我們將講解如下內(nèi)容:

  • 創(chuàng)建和安裝一個新的插件模塊
  • 完成插件模塊的聲明
  • 組織插件模塊文件結(jié)構(gòu)
  • 添加模型
  • 添加菜單項(xiàng)和視圖
  • 添加訪問權(quán)限
  • 使用腳手架命令來創(chuàng)建模塊

技術(shù)準(zhǔn)備

本章中,我們將預(yù)設(shè)你已安裝了Odoo并且按照第一章 安裝Odoo開發(fā)環(huán)境進(jìn)行的操作。你還應(yīng)熟悉第二章 管理Odoo服務(wù)器實(shí)例中所描述的查找和安裝附加的插件模塊。本章中所使用的代碼可以從如下GitHub倉庫中進(jìn)行下載:https://github.com/alanhou/odoo12-cookbook/tree/master/Chapter04/my_library

代碼實(shí)時操作的視頻請見:http://t.cn/E9PzDbm

引言

現(xiàn)在我們已經(jīng)有了開發(fā)環(huán)境并且知道如何管理Odoo實(shí)例和數(shù)據(jù)庫,可以學(xué)習(xí)如何創(chuàng)建Odoo插件模塊了。

這里我們的主要目標(biāo)是理解一個插件模塊的結(jié)構(gòu)是什么樣的以及對其進(jìn)行補(bǔ)充的典型增量工作流。本章中各節(jié)所討論的各種組件會在后續(xù)章節(jié)中進(jìn)行擴(kuò)充講解。

Odoo的插件模塊是什么?

除框架代碼以外,Odoo的所有基礎(chǔ)代碼都以模塊的形式組合在一起。這些模塊可以隨時從數(shù)據(jù)庫中安裝或卸載。這些模塊有兩大目的。要么你可以添加新應(yīng)用/業(yè)務(wù)邏輯,要么你可以修改已有應(yīng)用。簡言之,Odoo中的一切都始于模塊也終于模塊。

Odoo由不同規(guī)模的公司所使用,每個公司都有不同的業(yè)務(wù)流和要求。處理這一問題,Odoo將應(yīng)用的功能拆分到了不同的模塊中。這些模塊可按需在數(shù)據(jù)庫中進(jìn)行加載?;旧?,用戶可以在任何時間點(diǎn)啟用/禁用這些功能。因此,相同的軟件可以按不同的要求進(jìn)行調(diào)整。查看下面Odoo模塊的截屏;該列中第一個模塊是主應(yīng)用,其它的模塊為該應(yīng)用添加功能而設(shè)計(jì)。讓模塊列表按應(yīng)用分類進(jìn)行分組,進(jìn)入Apps菜單并對Category應(yīng)用分組:

image.png

如果你計(jì)劃在Odoo中開發(fā)新應(yīng)用,應(yīng)為不同功能設(shè)置邊界。這有助于將你的應(yīng)用切分為不同的插件模塊。既然你已經(jīng)知道了Odoo中插件模塊的用途,我們可以開始構(gòu)建自己的插件模塊了。

創(chuàng)建和安裝一個新的插件模塊

這一節(jié)中,我們將新建一個模塊,讓其在我們的Odoo實(shí)例中可用并安裝它。

準(zhǔn)備工作

我們需要準(zhǔn)備好一個Odoo實(shí)例來開始我們的開發(fā)。

如果我按照第一章 安裝Odoo開發(fā)環(huán)境從源碼輕松安裝Odoo一節(jié)進(jìn)行操作的話,Odoo應(yīng)該在~/odoo-dev/odoo下。為方便講解,我們假定Odoo安裝在該路徑下,但是你可以使用其它你自己偏好的路徑。

我們還需要一個位置來安裝自己的Odoo模塊。就本節(jié)而言,我們將使用odoo的同級目錄:~/odoo-dev/local-addon。

如何操作...

本章的示例中,我們將創(chuàng)建一個小型的插件模塊來管理圖書館中的一系列圖書。

如下步驟將創(chuàng)建并安裝一個新的插件模塊:

  1. 進(jìn)入到工作目錄即你要操作并放置新建的自定義模塊的插件目錄中:
$ cd ~/odoo-dev
    $ mkdir local-addons
  1. 為新模塊選擇一個技術(shù)名稱并使用該名稱作為模塊名創(chuàng)建目錄。本例中,我們將使用my_library:
$ mkdir local-addons/my_library
> ??模塊的技術(shù)名稱必須是有效的Python標(biāo)識符,需以字母開頭,僅包含字母、數(shù)字和下劃線。建議在模塊名稱中只使用小寫字母。
  1. 通過添加init.py文件來讓Python模塊可導(dǎo)入:
$ touch local-addons/my_library/__init__.py
  1. 為Odoo添加一個最小化的模塊聲明來將其作為一個插件模塊。創(chuàng)建manifest.py 文件并添加如下行:
{'name': 'My Library'}
  1. 啟動你的Odoo實(shí)例,將你的插件目錄添加到插件路徑中:
$ odoo/odoo-bin --addons-path=odoo/addon/,local-addons/
> ??如果在該Odoo命令中添加了 --save 選項(xiàng),插件路徑會被保存到配置文件中。下次你啟動服務(wù)時,如果沒有提供插件路徑選項(xiàng)的話,就會使用它。
  1. 讓這個新模塊在Odoo中可用;使用管理員登錄Odoo,啟動開發(fā)者模式,然后在Apps頂級菜單中選擇Update Apps List。現(xiàn)在Odoo就識別到了我們的模塊了。
  2. 選擇頂部的Apps菜單,在右上方的搜索欄中,刪除默認(rèn)的應(yīng)用過濾器并搜索my_library,點(diǎn)擊它的Install按鈕,就完成了安裝。

運(yùn)行原理...

Odoo模塊是一個包含代碼文件及其它資源的目錄。所使用的目錄名為模塊的技術(shù)名稱。模塊聲明中的 name 鍵對應(yīng)其標(biāo)題。

manifest.py文件是模塊的聲明。它包含一個帶有模塊元數(shù)據(jù)的Python字典,有分類、版本、它所依賴的模塊以及一系列它將要加載的數(shù)據(jù)文件。在這一節(jié)中,我們使用了最簡化的聲明文件,但在真實(shí)的模塊中,我們將使用其它的重要爭名。這將在下一節(jié)完成插件模塊的聲明是進(jìn)行討論。

模塊目錄必須是Python可導(dǎo)入的,因此即便目錄為空也要添加一個init.py 文件。要載入一個模塊,Odoo模塊將會導(dǎo)入它。這會導(dǎo)致init.py文件中的代碼被執(zhí)行,它作為運(yùn)行該模塊Python代碼的一個入口。因此,它通常會包含加載模塊Python文件及子模塊的一些重要聲明語句。

已識別模塊可通過命令行使用--init或-i選項(xiàng)直接安裝。這一模塊列表在提供插件路徑新建數(shù)據(jù)庫時獲取到的模塊進(jìn)行初始化設(shè)置??赏ㄟ^Update Module List菜單更新已有數(shù)據(jù)庫。

完成插件模塊的聲明

聲明文件對于Odoo模塊非常重要。它包含插件模塊重要的元數(shù)據(jù)并聲明了應(yīng)加載的數(shù)據(jù)文件。

準(zhǔn)備工作

我們應(yīng)當(dāng)有一個包含manifest.py聲明文件的模塊來進(jìn)行操作。你可能要按前一節(jié)的步驟來提供一個可以操作的模塊。

如何操作...

我們?yōu)檫@個插件模塊添加一個聲明文件和一個圖標(biāo):

  1. 以最相關(guān)的鍵名創(chuàng)建一個聲明文件,編輯模塊的manifest.py文件至內(nèi)容如下:
{
        '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'],
    }
  1. 為該模塊添加一個圖標(biāo),需選擇一個PNG圖像來供使用并將其拷貝至static/description/icon.png

運(yùn)行原理...

聲明文件中的內(nèi)容是一個常規(guī)的Python字典,包含鍵和值。我們的示例聲明中包含了大部分相關(guān)的鍵名:

  • name:這是該模塊的標(biāo)題。
  • summary:這是一個單行描述的副標(biāo)題。
  • description:這是一個以普通文本或重構(gòu)文本(RST)格式編寫的長描述。通常放在三個引號中,Python中使用三個引號來界定多行文本。RST的快速入門指南請見http://docutils.sourceforge.net/docs/user/rst/quickstart.html。
  • author:是一個作者姓名的字符串。如果有多個作者的話,一般使用逗號來進(jìn)行分隔,但注意它仍應(yīng)是一個字符串,而非Python列表。
  • website:這個 URL 可供人們訪問來了解模塊或作者的更多信息。
  • category:這用于在網(wǎng)絡(luò)上組織模塊。標(biāo)準(zhǔn)的分類名稱列表請見https://github.com/odoo/odoo/blob/12.0/odoo/addons/base/data/ir_module_category_data.xml。但也可以定義這些名稱以外的分類名稱。
  • version:這是該模塊的版本號??捎蒓doo應(yīng)用商店用于檢測已安裝模塊的新版本。如果版本號沒有以O(shè)doo目標(biāo)版本號(如12.0)開始,會進(jìn)行自動添加。但是,如果你顯式的聲明Odoo目標(biāo)版本號信息量會充足,比如用12.0.1.0.0或12.0.1.0來替代1.0.0或1.0。
  • depends:這是該模塊所直接依賴的模塊技術(shù)名稱列表。如果你的模塊不依賴于任何其它插件模塊,那么應(yīng)至少添加一個base模塊。別忘記包含這個模塊所引用的XML ID、視圖或模塊的定義模塊。那樣會確保它們以正確的順序進(jìn)行加載,避免難以調(diào)試的錯誤。
  • data:這是在模塊安裝或升級時需加載數(shù)據(jù)文件的相對路徑列表。這些路徑相對于模塊的根目錄。通常,這些是XML和CSV文件,但也可以使用YAML格式的數(shù)據(jù)文件。這些內(nèi)容會在第七章 模塊數(shù)據(jù)中深入討論。
  • demo:這是加載演示數(shù)據(jù)的文件的相對路徑列表。僅在創(chuàng)建數(shù)據(jù)庫時啟用了Demo Data標(biāo)記時都會進(jìn)行加載。

模塊圖標(biāo)使用的圖像是位于static/description/icon.png的一個PNG文件。

小貼士:Odoo的大版本一般會有較大的變化,因此如不進(jìn)行轉(zhuǎn)化或遷移操作的話,一個大版本中構(gòu)建的模塊不大可能與下一個版本進(jìn)行兼容。因此,在安裝模塊前確定Odoo的目標(biāo)版本號就非常的重要了。

擴(kuò)展內(nèi)容

也可以使用一個單獨(dú)的描述文件來替代模塊聲明中的長描述。自8.0版起,可通過后綴名為 .txt、.rst或.md(Markdown)的README文件來進(jìn)行替換。此外,可在模塊中包含一個description/index.html文件。

這個HTML描述會覆蓋掉聲明文件中所定義的描述。

還有一些常用的其它鍵名:

  • licence:默認(rèn)值為LGPL-3。這一標(biāo)識符用于模塊對外使用的證書。其它可用的證書有AGPL-3、Odoo自有證書v1.0(多用于付費(fèi)應(yīng)用)以及其它OSI核準(zhǔn)的證書。
  • application:如果為True,模塊作為應(yīng)用列出。通常這用于一個功能區(qū)的中央模塊。
  • auto_install:若為True,表示這是一個膠水模塊,在它所有的依賴模塊安裝后會被自動安裝。
  • installable:若為True(默認(rèn)值),表示該模塊可以進(jìn)行安裝。
  • external_dependencies:有些Odoo模塊內(nèi)部使用了Python/bin庫。如果你的模塊使用了這些庫,需要在這里進(jìn)行添加。如果列出的模塊在你的主機(jī)上沒有安裝的話則會停止該模塊的安裝。
  • {pre_init, post_init, uninstall}_hook:這是在安裝/卸載時調(diào)用的Python函數(shù)鉤子。更多詳細(xì)示例,請見第九章 高級服務(wù)端開發(fā)技巧。

組織插件模塊文件結(jié)構(gòu)

一個插件模塊包含代碼及其它資源文件,如XML文件和圖像。大多數(shù)這些文件,我們都可以自由選擇其在插件目錄中的存放位置。

但是,Odoo使用了一些模塊結(jié)構(gòu)的慣例,建議遵循這一慣例。

準(zhǔn)備工作

我們應(yīng)當(dāng)有一個插件模塊目錄,其中僅包含init.py和manifest.py文件。本節(jié)中,我們假定目錄為local-addons/my_library。

如何操作...

執(zhí)行如下步驟來為該插件模塊創(chuàng)建基本結(jié)構(gòu):

  1. 為代碼文件創(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
  1. 編輯模塊的頂級 init.py文件,這樣子目錄中的代碼會被加載到:
from . import models
    from . import controllers
這會給我們一個包含最常用目錄的入手結(jié)構(gòu),類似下面這樣:
.
    ├── __init__.py
    ├── __manifest__.py
    ├── controllers
    │   └── __init__.py
    ├── data
    ├── demo
    ├── i18n
    ├── models
    │   └── __init__.py
    ├── static
    │   └── description
    │       └── icon.png
    └── views

運(yùn)行原理...

為大家普及一下背景,Odoo插件模塊可以有三種類型文件:

  • Python代碼init.py加載,通過該文件導(dǎo)入.py文件及代碼子目錄。子目錄中包含的Python代碼,再由其內(nèi)部的init.py導(dǎo)入。
  • 模塊聲明文件manifest.py中data和demo鍵名所聲明供加載的數(shù)據(jù)文件通常是用戶界面、fixture數(shù)據(jù)和演示數(shù)據(jù)中會使用到的XML和CSV文件。還可使用YAML文件,可以包含一些模塊加載時運(yùn)行的過程指令,例如,通過程序生成或更新記錄而非在XML文件中加入數(shù)據(jù)。
  • 網(wǎng)頁資源,如JavaScript代碼和庫、CSS、SASS和QWeb/HTML模板。這些文件用于在 UI 元素中構(gòu)建UI組成部分及管理用戶動作。它們通過繼承主模板的XML文件來進(jìn)行聲明,用于為網(wǎng)頁客戶端或網(wǎng)站頁面添加這些資源。

插件文件以如下目錄進(jìn)行組織:

  • models/包含后端代碼文件,用于創(chuàng)建模型及其業(yè)務(wù)邏輯。推薦每個模型一個文件并使用與模型相同的名稱,例如 library.book模型的對應(yīng)文件為library_book.py。這些在第五章 應(yīng)用模型中會進(jìn)行深入講解。
  • views/包含用于用戶界面的XML文件,包含動作、表單、列表等等。類似于模型,建議每個模型一個文件。網(wǎng)站模塊的文件名通常以_template后綴進(jìn)行結(jié)尾。后端視圖在第十章 后端視圖中講解,網(wǎng)站視圖在第十五章 CMS網(wǎng)站開發(fā)中進(jìn)行講解。
  • data/包含模塊初始數(shù)據(jù)的其它數(shù)據(jù)文件。數(shù)據(jù)文件在第七章 模塊數(shù)據(jù)中進(jìn)行講解。
  • demo/包含帶演示數(shù)據(jù)的數(shù)據(jù)文件,對于測試、培訓(xùn)或模塊評測都非常有用。
  • Odoo會在i18n/中查找.pot及.po翻譯文件。更多詳情參見第十二章 國際化。這些文件無需在聲明文件中提及。
  • security/包含定義訪問控制列表的數(shù)據(jù)文件,通常是一個ir.model.access.csv文件,也可以是一個XML文件,用于定義權(quán)限組及行級權(quán)限的記錄規(guī)則。參見第十一章 權(quán)限安全來獲取更多內(nèi)容。
  • controllers/包含網(wǎng)站控制器的代碼文件,用于為模塊提供各種功能。網(wǎng)頁控制器在第十四章 網(wǎng)頁服務(wù)端開發(fā)中進(jìn)行講解。
  • static/用于放置所有的網(wǎng)頁資源。和其它目錄不同,該目錄名不只是一種慣例。這一目錄中的文件無需用戶登錄即可對外提供訪問。該目錄多包含JavaScript、樣式表、圖像等文件。它們無需在模塊聲明文件中進(jìn)行提及,但需要在網(wǎng)頁模板中引用。這會在第十五章 CMS網(wǎng)站開發(fā)中進(jìn)行討論。

小貼士:在向模塊添加新文件時,不要忘記在manifest.py(數(shù)據(jù)文件)或init.py(代碼文件)文件中進(jìn)行聲明,否則會忽略這些文件而不進(jìn)行加載。

添加模型

數(shù)據(jù)結(jié)構(gòu)中定義的模型會用于我們的業(yè)務(wù)應(yīng)用。這一節(jié)向讀者展示如何為模塊添加基本模型。

在我們的示例中,希望對圖書館的書籍進(jìn)行管理。那么,我們需要創(chuàng)建一個代表書籍的模型。每本書包含書名及一名或多名作者。

準(zhǔn)備工作

我們需要有一個模塊來進(jìn)行操作。如果你按照本章第一節(jié)創(chuàng)建和安裝一個新的插件模塊操作的話,則會有一個名為my_library的空模塊。我們將使用它來做進(jìn)一步講解。

如何操作...

要添加新模型,我們需要添加一個Python文件來描述它,然后升級插件模塊(如未安裝則執(zhí)行安裝)。以下使用的路徑為我們的插件模塊目錄中的相對路徑(例如,~/odoo-dev/local-addons/my_library/):

  1. 為模塊添加一個 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'
        )
  1. 在模塊中添加一個Python初始化文件models/init.py來加載代碼,內(nèi)容如下:
from . import library_book
  1. 編輯模塊的Python初始化文件來在模塊中加載models/目錄:
from . import models
  1. 從命令行或用戶界面中的Apps菜單中升級該Odoo模塊。如果你在升級模塊時仔細(xì)查看服務(wù)日志的話,會看到如下行:
odoo.modules.registry: module my_library: creating or updating database table

然后,就可以在我們的Odoo實(shí)例中使用這一新的library.book模型了。有兩種方式來查看我們的模型是否在數(shù)據(jù)庫中進(jìn)行了添加。

第一種方式是你可以在用戶界面中進(jìn)行查看。激活開發(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;

運(yùn)行原理...

第1步中我們在模塊中創(chuàng)建一個了一個Python文件。

Odoo框架有著其自己的ORM框架。這一ORM對PostgreSQL數(shù)據(jù)庫進(jìn)行了抽象。通過繼承Odoo Python類Model,我們可以創(chuàng)建自己的模型(數(shù)據(jù)表)。在定義新模型時,也將其加入到了中央模型倉庫中。這讓其它模塊在之后對其進(jìn)行修改變得更為容易。

模型有一些以下劃線為前綴的通用屬性。最重要的一個是_name,它提供了一個唯一內(nèi)部標(biāo)識符來在Odoo實(shí)例中進(jìn)行使用。ORM會根據(jù)這個屬性來生成數(shù)據(jù)表。本節(jié)中,我們使用了_name = 'library.book'?;谶@一屬性,該ORM框架會創(chuàng)建一個名為library_book的新數(shù)據(jù)表。注意ORM在創(chuàng)建新表的名稱時會通過將_name屬性中的. 替換為 _ 。

模型字段以類型屬性的方式進(jìn)行定義。我們首先以Char類型定義了name字段。模型中有這一字段會非常方便,因?yàn)槟J(rèn)在其它模型中引用該模型時,它會用作記錄描述。

我們還使用了一個關(guān)聯(lián)字段的示例author_ids。這在圖書和其作者之前建立了一個多對多的關(guān)聯(lián)。一本書可以有多個作者,而每個作者也可以編寫多本書。

有關(guān)模型有很多可以討論的地方,我們將在第五章 應(yīng)用模型中進(jìn)行深度講解。

接下來,我們必須讓我們的模塊可以識別到這一新的Python文件。這通過init.py文件來實(shí)現(xiàn)。因?yàn)閷⒋a放在了models/子目錄內(nèi),我們需要前述的init.py 文件來導(dǎo)入該目錄,其中又應(yīng)包含另一個init.py文件,在其中導(dǎo)入那里的每一個代碼文件(本例中只有一個文件)。

對Odoo模型的修改通過升級該模型來啟用。Odoo服務(wù)會處理由模型類到數(shù)據(jù)庫結(jié)構(gòu)變化的轉(zhuǎn)換。

雖然此處沒有提供示例,業(yè)務(wù)邏輯也可以在這些Python文件中進(jìn)行添加,或通過對模型類添加新的方法,或繼承已有方法,如create() 或 write()。這在第六章 基本服務(wù)端部署中進(jìn)行討論。

添加菜單項(xiàng)和視圖

在有了我們的數(shù)據(jù)結(jié)構(gòu)所需的模型之后,我們希望用戶可以通過用戶界面與它們進(jìn)行交互。本節(jié)基于上一節(jié)的圖書模型進(jìn)行創(chuàng)建,添加一個菜單項(xiàng)來顯示一個包含列表和表單視圖的用戶界面。

準(zhǔn)備工作

需要有實(shí)現(xiàn)library.book模型的插件模塊,這在上一節(jié)中已經(jīng)提供到。使用的路徑為相對插件模塊所處位置的相對路徑(如~/odoo-dev/local-addons/my_library/)。

如何操作...

要添加一個視圖,我們將添加一個XML文件,其中包含對于模塊的定義。因其是一個新模型,我們還應(yīng)添加一個菜單選項(xiàng)來讓用戶可以訪問它。

注意下述步驟的順序也是很重要的,因?yàn)槠渌囊恍玫皆谥安襟E中定義的ID:

  1. 創(chuàng)建一個XML文件views/library_book.xml來添加描述用戶界面的數(shù)據(jù)記錄:
<?xml version="1.0" encoding="utf-8"?> 
    <odoo> 
    <!-- Data records go here --> 
    </odoo>
  1. 在插件模塊聲明文件manifest.py中添加新的數(shù)據(jù)文件,通過views/library_book.xml來進(jìn)行添加:
{
     'name': "My Library",
     'summary': "Manage books easily",
     'depends': ['base'],
     'data': ['views/library_book.xml'],
    }
  1. 在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>
  1. 在library_book.xml文件中添加菜單項(xiàng),讓其對用戶可見:
<menuitem name="My Library" id="libray_base_menu" />
    <menuitem name="Books" id="library_book_menu"
              parent="libray_base_menu" action="library_book_action" />
  1. 在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>
  1. 在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>
  1. 在library_book.xml文件中添加自定義搜索選項(xiàng):

        <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 用戶必須要獲取相應(yīng)的訪問權(quán)限才能在用戶界面中訪問我們的模型。在沒有賦予相應(yīng)的訪問權(quán)限時,Odoo是不會顯示你的菜單和視圖的在下一節(jié)中,我們將為我們的模型添加訪問權(quán)限,在那之后你才可以通過admin用戶來查看這些菜單和視圖。

以超級用戶訪問 Odoo

通過將admin轉(zhuǎn)換為超級用戶superuser,你就可以不受訪問權(quán)限的限制,因此無需授予訪問權(quán)限即可訪問所有菜單和視圖。要將admin用戶轉(zhuǎn)換為superuser,先激活開發(fā)者模式。然后在開發(fā)者工具選項(xiàng)中,點(diǎn)擊Become super user選項(xiàng)。

以下截圖供您參考:

image.png

在成為超級用戶之后,你的菜單會顯示一個條狀背景,如下圖所示:

image.png

這時如果你試著升級模塊,則會看到一個新的菜單選項(xiàng)(可能會需要刷新瀏覽器)。點(diǎn)擊Books菜單會打開圖書模型的列表視圖,如下圖所示:

image.png

運(yùn)行原理...

在底層中,用戶界面由存儲在特定模型中的記錄所定義。前兩步中創(chuàng)建了一個空的XML文件來定義待加載的記錄,然后將它們添加到模型的數(shù)據(jù)文件列表中來供安裝。

數(shù)據(jù)文件可以放在該模型目錄中的任意位置,但按照習(xí)慣用戶界面的數(shù)據(jù)文件在views/子目錄中定義。通常,這些文件的名稱是基于模型的名稱的。本例中,我們?yōu)閘ibrary.book模型創(chuàng)建用戶界面,因此我們創(chuàng)建了views/library_book.xml文件。

下一步是定義在客戶端主區(qū)域用戶界面中顯示的窗口動作。該動作有一個由 res_model,定義的目標(biāo)模型,name屬性用于在用戶打開動作時向用戶所顯示的標(biāo)題。這些都是基本屬性。窗口動作還支持其它屬性,讓我們對視圖渲染方式擁有更多的控制,比如顯示什么視圖,為可用的記錄添加過濾器或設(shè)置默認(rèn)值。這些會在第十章 后端視圖中進(jìn)行討論。

通常,數(shù)據(jù)記錄使用<record>標(biāo)簽定義,在本例中我們?yōu)閕r.actions.act_window模型創(chuàng)建了一條記錄。這會創(chuàng)建窗口動作。

類似地,菜單項(xiàng)存儲在ir.ui.menu模型中,我們可以使用<record>標(biāo)簽來進(jìn)行創(chuàng)建。但是在Odoo中有一個名為<menuitem>的快捷標(biāo)簽,因此我們在本例中進(jìn)行了使用。

以下是菜單項(xiàng)的主要屬性:

  • name:這是要顯示的菜單項(xiàng)文本。
  • action:這是要執(zhí)行的動作的標(biāo)識符。我們使用前一步中所創(chuàng)建的窗口動作ID。
  • sequence:這用于設(shè)置同級菜單項(xiàng)的顯示順序。
  • parent:這是父級菜單項(xiàng)的標(biāo)識符。本例中的菜單項(xiàng)沒有父級,即它會顯示在頂級菜單中。

至此,我們還沒有在模型中定義任何視圖。但是,如果這時你升級了該模型,Odoo會自動地實(shí)時為你創(chuàng)建視圖。可是,我們一定會想要控制視圖的展示內(nèi)容,因此,在接下來的兩步中創(chuàng)建了一個表單視圖和一個樹狀視圖。

這兩個視圖通過 ir.ui.view 模型上的一條記錄進(jìn)行定義。我們所使用的屬性如下:

  • name:這是標(biāo)識視圖的標(biāo)題。在Odoo的源碼中,你會發(fā)現(xiàn)這里重復(fù)使用了XML ID,但是你完全可以添加一個更易于閱讀的名稱作為標(biāo)題。

    小貼士:如果省略了name字段,Odoo會使用模型名稱及視圖類型來生成一個。對于新模型的標(biāo)準(zhǔn)視圖這完全沒有問題。在繼承視圖時建議使用一個更具說明性的名稱,因?yàn)檫@會讓你在Odoo用戶界面上查找具體視圖時更為方便。

  • model:這是目標(biāo)模型的內(nèi)部標(biāo)識符,和_name屬性中的所定義的名稱一致。

  • arch:這是視圖結(jié)構(gòu),實(shí)際定義結(jié)構(gòu)的地方。這里不同類型的視圖會有不同。

表單視圖在頂級<form>元素中定義,它的畫布是一個兩列網(wǎng)格。在表單內(nèi),<group>元素用于在垂直方向上編排字段。兩個組會生成包含<field>元素所定義字段的兩個列。字段根據(jù)數(shù)據(jù)類型使用其默認(rèn)組件,但可以使用widget屬性來指定所要使用的組件。

樹狀視圖要簡單些,它們以包含用于各列中顯示的<field>元素的頂級<tree>元素定義。

最后,我們添加了搜索視圖來在右上角的搜索框中擴(kuò)展搜索選項(xiàng)。在頂級的<search>標(biāo)簽中,可以包含<field>和<filter>元素。字段元素是在搜索視圖中可用于搜索的其它字段。過濾器元素為可通過點(diǎn)擊激活的預(yù)置過濾條件。這些話題會在第十章 后端視圖中進(jìn)行討論。

添加訪問權(quán)限

在添加新的數(shù)據(jù)模型時,你需要定義誰可以創(chuàng)建、讀取、更新和刪除記錄。在創(chuàng)建一個全新的應(yīng)用時,這可能還包含新的用戶組的定義。因此,如果用戶沒有訪問權(quán)限的話,Odoo則不會該顯示菜單和視圖。在上一節(jié)中,我們將admin用戶轉(zhuǎn)換為超級用戶來訪問這個菜單。在學(xué)完本節(jié)后,你就可以直接以admin用戶來訪問我們圖書模塊的菜單和視圖了。

這一節(jié)使用上一節(jié)中的定義的圖書模型,會定義一個用戶安全組來控制誰能夠訪問或修改書籍記錄。

準(zhǔn)備工作

我們會需要上一節(jié)中實(shí)現(xiàn)了library.book模型的插件模塊,因?yàn)樵谶@一節(jié)我們會為其添加權(quán)限規(guī)則。使用的是插件模塊所在位置(例如~/odoo-dev/local-addons/my_library/)的相對路徑。

如何操作...

我們要在本節(jié)中添加的安全規(guī)則如下:

  • 所有人均可閱讀圖書記錄
  • 名為Librarians的新用戶組擁有創(chuàng)建、閱讀、更新和刪除書籍記錄的權(quán)限

要進(jìn)行實(shí)現(xiàn),我們需要執(zhí)行如下步驟:

  1. 創(chuàng)建一個名為security/groups.xml的文件并添加如下內(nèi)容:
<?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>
  1. 添加一個名為security/ir.model.access.csv的文件并加入如下內(nèi)容:
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
  1. manifest.py中添加這兩個數(shù)據(jù)文件:
# ...
    'data': [
        'security/groups.xml',
        'security/ir.model.access.csv',
        'views/library_book.xml'
    ],
    # ...

在實(shí)例中更新插件后即可使用新定義的權(quán)限規(guī)則了。

運(yùn)行原理...

我們提供了兩個新數(shù)據(jù)文件并添加到了插件模塊的聲明文件中,這樣安裝或升級該模塊時會在數(shù)據(jù)庫中加載它們:

  • security/groups.xml通過創(chuàng)建一條res.groups記錄來定義一個新權(quán)限組。我們通過admin用戶的引用ID base.user_admin為其授予了Librarians的權(quán)限,這樣admin用戶將擁有l(wèi)ibrary.book模型的權(quán)限。
  • ir.model.access.csv通過組來關(guān)聯(lián)模型的權(quán)限。第一行g(shù)roup_id:id列為空,表示該規(guī)則適用于所有人。最后一行授予了我們剛剛創(chuàng)建的組的成員所有權(quán)限:

小貼士:聲明文件中data版塊內(nèi)文件的順序非常重要,創(chuàng)建權(quán)限組的文件必須要在列出安全權(quán)限的文件之前加載,因?yàn)榘踩珯?quán)限的定義依賴于組的存在。因?yàn)橐晥D可具體到權(quán)限組,我們推薦將組的定義文件放在該列表中會更為保險。

其它內(nèi)容

使用腳手架命令來創(chuàng)建模塊

在新建 Odoo 模塊時,需要設(shè)置一些范本代碼。為幫助大家快速新建模塊,Odoo提供了scaffold(腳手架)命令。

本節(jié)向你展示如何使用scaffold命令新建一個模塊,它會創(chuàng)建一個目錄和文件結(jié)構(gòu)來供使用。

準(zhǔn)備工作

我們將在一個自定義模塊目錄中新建一個插件模塊,因此需要已安裝Odoo并且給自定模塊一個目錄。假定Odoo安裝的位置為/odoo-dev/odoo,我們的自定義模塊會放置在/odoo-dev/local-addons目錄中。

如何操作...

我們將使用scaffold命令來創(chuàng)建樣例代碼。按照給定的步驟來使用scaffold命令新建一個模塊:

  1. 更改工作目錄到想要放置模塊的地方。它可以是你所選擇的任意目錄,但需要在一個插件路徑中才可進(jìn)行使用。按照我們在前面小節(jié)中所選擇的目錄,應(yīng)該是這樣的:
$ cd ~/odoo-dev/local-addons
  1. 為這個新模塊選擇一個技術(shù)名稱,并使用scaffold命令來創(chuàng)建它。本例中,我們選擇的是my_module:
$ ~/odoo-dev/odoo/odoo-bin scaffold my_module
  1. 編輯默認(rèn)聲明文件manifest.py并修改相應(yīng)的值。你一定會想要修改name鍵中的模塊標(biāo)題。

以下是生成的插件模塊的結(jié)構(gòu):

$ 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)在你應(yīng)編輯各個生成的文件來適應(yīng)你對新模塊的需求。

運(yùn)行原理...

scaffold命令創(chuàng)建基于一個模板的新模塊結(jié)構(gòu)。

默認(rèn),這個新模塊在當(dāng)前工作目錄中進(jìn)行創(chuàng)建,但我們也可以指定一個目錄來創(chuàng)建該模塊,將其作為一個額外的參數(shù)進(jìn)行傳遞。

參考如下示例:

$ ~/odoo-dev/odoo/odoo-bin scaffold my_module ~/odoo-dev/local-addons

此處使用了一個默認(rèn)模板,但也可以為網(wǎng)站主題編寫的主題模板??梢允褂?-t選項(xiàng)來選擇一個指定的模板。我們也可以使用包含模板的一個目錄來作為路徑。

這表示我們可以通過scaffold命令來使用我們自己的模板。內(nèi)置的主題可作為一個向?qū)?,可以?/odoo/cli/templates這個Odoo子目錄中找到。我們可以用類似下面的命令來使用我們自己的模板:

$ ~/odoo-dev/odoo/odoo-bin scaffold -t path/to/template my_module
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容