【odoo14】【好書學習】第三章、創建插件


老韓頭的開發日常【好書學習】系列

現在我們已經有了開發環境並了解了如何管理實例及數據庫,現在讓我們來學習下如何創建插件模塊。
本章內容如下:

  • 創建和安裝模塊
  • 完成manifest文件
  • 組織模塊文件結構
  • 添加模型
  • 添加菜單及視圖
  • 添加訪問控制
  • 使用scaffold命令創建模型

在odoo中什么是模塊(add-on module)?

除了框架代碼,其他的代碼都是以模塊的形式組織起來的。這些模塊可以隨時安裝和卸載。由於odoo用於各種規模的公司,每一個公司都有自己的業務流程。為了解決這一個問題,應用將應用拆分到不同的模塊當中。這些模塊在需要的時候才會被載入。我們可以隨時啟停這些功能。同一個應用也可以適配不同的需求。如下截圖當中是以不同的應用分組,每一組第一個應用是主模塊,其余的是屬於其輔助模塊。

在創建應用時應該創建各個功能的邊界。這將非常有助於將應用程序划分為不同的附加模塊。下面讓我們開始構建自己的附加模塊了。

創建和安裝新應用

准備

在用的odoo實例

步驟

作為例子,我們這一章將創建一個管理圖書的模塊。

  1. 進入項目工程,創建本地目錄。
$ cd ~/odoo-dev
$ mkdir local-addons
  1. 創建項目目錄
$ mkdir local-addons/my_library
  1. 創建__init__.py文件
$ touch local-addons/my_library/__init__.py
  1. 創建__manifest__.py文件,並寫入
{'name': 'My Library'}
  1. 將本地目錄配置到odoo路徑中。
$ odoo/odoo-bin --addons-path=odoo/addon/,local-addons/

如果我們在命令行中使用--save,那么相應的配置會存儲的配置文件下次使用的時候就會更方便了。
6. 通過在APP頁面刷新本地目錄按鈕,可以在列表當中查看到我們新建的項目。

  1. 安裝

原理

odoo模塊是包含着源代碼及其他文件的目錄。該文件夾名稱通常是模塊的技術名稱。
manifest.py是Python的字典包含着模塊兒的相關信息。
模塊必須是可導入的,也就是說它必須具備__init__.py文件,即使這個文件時空的。

完成模塊的__manifest__.py文件

准備

上一節內容

步驟

  1. 編輯__manifest__.py文件
'name': "My library",
'summary': "Manage books easily",
'description': """
Manage Library
==============
Description related to library.
""",
'author': "Your name",
'website': "http://www.example.com",
'category': 'Uncategorized',
'version': '13.0.1',
'depends': ['base'],
'data': ['views/views.xml'],
'demo': ['demo.xml'],
}
  1. 為模塊選擇一個icon圖標,放置在static/description/icon.png中。

原理

  • name: 模塊的名稱。
  • summary: 模塊的簡單介紹。
  • description: 模塊的長介紹。通常是純文本或者ReStructuredText (RST) 格式。
  • author: 模塊作者。
  • website: 模塊開發者的網站。
  • category: 模塊的分類。關於模塊分類有一個標准的列表可供選擇( https://github.com/odoo/ odoo/blob/13.0/odoo/addons/base/data/ir_module_category_ data.xml. )。當然你也可以定義自己的名稱。
  • version: 模塊的版本。這通常用於odoo檢測是否有新的版本需要升級。如果所輸入的版本當中並不包含包含odoo的主版本(12.0,13.0,14.0),odoo將自動添加。
  • depends: 這是當前模塊所依賴的其他模塊。即便模塊不依賴於其他的模塊兒的話,要么也應該輸入base模塊。在填寫依賴的時候應注意依賴的順序。
  • data: 這是數據文件的列表。數據文件的路徑是相對於模塊的根路徑的通常是xml及csv文件。也可以是yaml文件,這在第六章進行介紹。
  • demo: 這關聯模塊兒的演示數據。
    由於odoo主版本之間存在蠻多的不同一個模塊兒,可能並不是用於其他的版本。

更多

在__manifest__.py的description中,也可以是單獨的描述性文件。自odoo8之后,支持README文件或者其他的txt、rst、md擴展名的文件。或者直接展示在description/index.html的內容。
html文件將直接復寫描述中的內容。
還有幾個關鍵的key

  • licence: 默認是LGPL-3協議。
  • application: True/False,當前模塊是否是核心模塊。
  • auto_install: True/False,代表是否在其所依賴的模塊完成安裝后自動安裝。
  • installable: True/False,代表當前模塊是否可安裝。
  • external_dependencies: 一些模塊可能依賴於Python或bin包。如果當前環境不具備,這些內容那么安裝將停止。
  • {pre_init, post_init, uninstall}_hook: 這里代表python的函數,分別是安裝前,安裝后,卸載時運行(詳細將在第八章介紹)
    還有幾個特殊的key
  • price: 代表當前模塊兒的售價,如果沒有設置的話,那么代表免費。
  • currency: 代表當前模塊兒售價的單位。默認是EUR。
  • live_test_url: 表示在線試用的鏈接。
  • iap: 如果模塊提供IAP服務,請填寫IAP的key。
  • images: images的路徑,這些圖片用於在odoo的app商城上展示。

組織模塊文件結構

模塊當中包含源代碼及其他各種各樣的文件,雖然我們可以隨便放置,但是建議還是按照模塊的結構進行規范化。

准備

假定我們的模塊位於local-addons/my_ library,並包含了__manifest__.py,__init__.py文件。

  1. 創建目錄及文件
$ cd local-addons/my_library
$ mkdir models
$ touch models/__init__.py
$ mkdir controllers
$ touch controllers/__init__.py
$ mkdir views
$ touch views/views.xml
$ mkdir security
$ mkdir wizard
$ touch wizard/__init__.py
$ mkdir report
$ mkdir data
$ mkdir demo
$ mkdir i18n
  1. 編輯__init__.py文件
from . import models
from . import controllers
from . import wizard

大部分目錄結構式如下

my_library
├── __init__.py
├── __manifest__.py
├── controllers
│ └── __init__.py
├── data
├── demo
├── i18n
├── models
│ └── __init__.py
├── security
├── static
│   ├── description
│ └── src
│ ├─ js
│ ├─ scss
│ ├─ css
│ └ xml
├── report
├── wizard
│ └── __init__.py
└──views
└── __init__.py

原理

odoo中主要有三種類型的文件

  • Python: .py文件,包含模型對象、業務邏輯
  • Data文件: 定義在data及demo的key中。通常是XML及CSV文件。YAML文件也可以,他可以在模塊加載的時候執行一些指令。對於實例而言,相較於xml的靜態更新,yaml可以實現動態生成和更新記錄。
  • Web assets是JavaScript、CSS、SCSS及QWeb/HTML模板的集合。這些文件通常用於構建友愛頁面以及管理用戶的點擊行為。還有一些被定義為XML的文件,去擴成主模板的功能。

模塊文件通過如下方式進行組織:

  • models/: 包含模塊的模型對象定義及其業務邏輯。詳見第四章應用模型
  • views/: 包含定義用戶交互的xml文件。包括動作、form視圖、list視圖等。建議每一個模型都有單獨的xml文件。網站模板的文件名建議以_template后綴。后端視圖將在第九章后端視圖介紹,網站視圖將在第十四章CMS開發介紹。
  • data/: 包含模型的初始化數據。將在第六章管理模塊數據介紹。
  • demo/: 包含演示數據,用於測試。
  • il8n/: 用於存放翻譯文件。以.pot及.po文件為主。將在第十一章,國際化中進行介紹。
  • security/: 包含權限控制的相關文件。包括ir.model.access.csv,xml文件(定義權限組及記錄規則信息)。詳見第十章權限控制。
  • controllers/: 包含web網站的訪問定義等業務邏輯。詳見第十三章,web服務開發。
  • static/: 網站相關的定義文件。這里的文件是允許非登錄用戶訪問的。主要包括JavaScript、樣式文件及images。這並不需要在manifest中引用,但需要在web模板中引用。詳見第十四章,CMS開發。
  • wizard/: 包含向導相關的文件。在odoo中,wizard用於保存中間數據。詳見第八章,服務端開發-進階。
  • report/: odoo提供了生成pdf文件的特性。這里將用於生成的pdf報告的相關文件。詳見第十二章,自動化、流程、郵件及打印。

當我們添加了新的文件后,不要忘記在__manifest__.py及__init__.py中進行引用。

添加模型

模型定了我們業務邏輯中的數據結構。
在這一章節當中,我們將添加圖書模型。

准備

步驟

  1. 添加模型文件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. 將新增文件添加到models/init.py
from . import library_book
  1. 編輯模塊的初始化文件__init__.py
from . import models
  1. 通過頁面UI或者命令行更新模塊
    現在模型已添加到數據庫中了。可通過兩種方式查看:
  2. 通過odoo的頁面,在菜單 Settings|Technical|Database Structure|models下查找目標模型。
  3. 進入數據庫查看
$ psql test-13.0
test-13.0# \d library_book;

原理

odoo中有自己的的Object Relations Mapping(ORM)框架。orm框架提供了對postgresql數據庫的抽象。通過繼承odoo的python類model,我們能夠創建自己的模型。
模型有幾個通用的以_為前綴的屬性。最重要的是_name,它是模型的唯一標識。ORM框架生成數據庫表也是基於這個屬性。數據庫表明是將name中的”.“替換為”_“。
我們新增了模型文件后,需要將其添加到同目錄的__init__.py文件中。

添加菜單及視圖

這節我們將實現頁面菜單及視圖的展示。

准備

步驟

菜單和視圖都是以xml文件的形式存在。

  1. 創建xml文件以添加數據記錄,views/library_book.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Data records go here -->
</odoo>
  1. 將新增的xml文件添加到__manifest__.py文件中
{
'name': "My Library",
'summary': "Manage books easily",
'depends': ['base'],
'data': ['views/library_book.xml'],
}
  1. 在library_book.xml中添加動作action(用於打開視圖)
<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_mode">tree,form</field>
</record>
  1. 添加菜單,並將action關聯到菜單上
<menuitem name="My Library" id="library_base_menu" />
<menuitem name="Books" id="library_book_menu" parent="library_base_menu" action="library_book_action"/>
  1. 在library_book.xml中添加form視圖
<record id="library_book_view_form" model="ir.ui.view">
	<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. 添加tree(list)列表視圖
<record id="library_book_view_tree" model="ir.ui.view">
	<field name="name">Library 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. 添加搜索視圖
<record id="library_book_view_search" model="ir.ui.view">
	<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 Authors"
			name="without_author"
			domain="[('author_ids','=',False)]"/>
		</search>
	</field>
</record>
  1. 當一個新的模型添加到odoo中后,默認是沒有訪問權限的,這樣菜單及視圖也是看不到的。我們可以通過進入超級管理員模式去查看相關內容。

進入超級管理員模式

進入管理員模式后,右上角視圖將變成

原理

數據文件可以放在模塊目錄中的任何位置,但約定是在視圖/子目錄中定義用戶界面。通常,這些文件的名稱基於模型的名稱。在本例中,我們正在為圖書館.book模型,所以我們創建了 views/library_book.xml文件。
下一步是定義一個窗口操作。動作操作的目標模型定義在res_model中,name屬性用於在用戶打開動作時向用戶顯示標題。這些只是基本屬性。窗口操作支持附加屬性,從而可以更有效地控制視圖的呈現方式,例如顯示哪些視圖、在可用記錄上添加過濾器或設置默認值。在第9章后端視圖中詳細討論了這些問題。
通常,數據記錄是使用 標記定義的,並將記錄添加到模型ir.actions.action_window的數據庫表中。
相似,菜單是添加到ir.ui.menu模型中。我們也可以使用 的簡化標簽。
下面是菜單的主要屬性:

  • name: 菜單展示的內容
  • action: 點擊菜單后出發的動作
  • sequence: 菜單的展示順序
  • parent: 代表當前菜單所屬的父級菜單
  • web_icon: 標識顯示在菜單上的icon圖標。這個只在企業版生效。
    截止目前,我們還沒有添加視圖。但是如果我們更新模塊,那么odoo將自動創建默認的視圖。
    所有的視圖都是定義在ir.ui.view模型中的。主要屬性如下:
  • name: 視圖的標題。如果沒寫,odoo將視同模型的名稱及視圖的類型自動生成一個。
  • model: 這是視圖所屬的模型。
  • arch: 這是視圖的架構。
    Form視圖是定義在
    元素中的,通過 進行組織展示的元素。
    Tree視圖定義在 ,Search視圖定義在

添加訪問控制

在我們的前面提到的model、view、menu都涉及到權限控制。
在odoo中,權限是以組的形式展開的。用戶屬於某些權限組,通過對權限組進行授權實現對model、view、menu的控制。

准備

步驟

  1. 權限組,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>
  1. 通過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
  1. 將以上文件添加到__manifest__.py中
# ...
'data': [
'security/groups.xml',
'security/ir.model.access.csv',
'views/library_book.xml'
],
# ...

原理

以上我們涉及了權限組的創建及對權限組進行模型授權

  • security/groups.xml,定義了權限組,id為權限組的唯一標識,name是權限組的名稱,users是權限組初始化時包含的用戶。其實groups也是將權限組的記錄寫入res.groups模型中。
  • ir.model.access.csv文件,定義了權限組對於模型的訪問權限。其實就是將csv中的信息寫入ir.model.access模型中。

使用scaffold命令創建模型

之前我們自己構建了模塊的結構,但是其實odoo提供了簡單構建模塊的命令: scaffold。

准備

步驟

  1. 進入本地模塊所在目錄,如下:
$ cd ~/odoo-dev/local-addons
  1. 通過命令創建模塊, scaffold 模塊的技術名稱
$ ~/odoo-dev/odoo/odoo-bin scaffold my_module
  1. 如下是命令自動創建的模塊架構
$ tree my_module
my_module/
├── __init__.py
├── __manifest__.py
├── controllers
│ 	├── __init__.py
│ 	└── controllers.py
├── demo
│ 	└── demo.xml
├── models
│ 	├── __init__.py
│ 	└── models.py
├── security
│ 	└── ir.model.access.csv
└── views
	├── templates.xml
	└── views.xml
5 directories, 10 files

原理

scaffold是基於模板創建新模塊的。
默認是創建在當前目錄下,也可指定存儲的目錄。

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

odoo中是有兩個模板的,處於/odoo/cli/templates目錄中。一個是默認的模板,另一個主要用於網站主題。當然我們也可以使用我們自己的模板。通過-t指定模板存儲的路徑。

 $ ~/odoo-dev/odoo/odoo-bin scaffold -t path/to/template my_ module


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM