Odoo 12開發之后台視圖 – 設計用戶界面
一·菜單項
# 菜單項形成一個層級結構,最頂層結構
# name 是展示在用戶界面中的菜單標題
# action 是點擊菜單時運行的窗口
# parenter 是父級菜單項XML ID
# sequence 設置一個數字來在展示菜單項時進行排序. 如sequence="10"
# groups 用來都好分割可訪問菜單安全組的xml ID列表
# web_icon 菜單項的圖標
<menuitem id="menu_library_checkout"
name="Checkout"
action="action_library_checkout"
parent="library_app.menu_library" />
二·窗口操作(Window Actions)
# 通常用於菜單項或視圖中的按鈕.
# 窗口操作存儲在ir.actions.act_window模型中.
# 可通過域過濾器過濾出可用的記錄,設置默認值以及從上下文屬性中過濾
# name 是視圖顯示的標題
# res_model是目標模型的標識符
# view_mode是一個逗號分割的可用視圖類型列表
# target 是設置對話窗口打開方式,如target="new",默認是current
# context 是視圖設置上下文信息. 可設置默認值或者啟用過濾器等.context=”{‘default_user_id’: uid}”
# domain 是對可在視圖種瀏覽的記錄強制過濾,domain="[('user_id','=',uid)]"
# limit 列表視圖每頁顯示的記錄數
# src_model 設置Action所作用的模型,例如src_model=”library.checkout”
#
<act_window id="action_library_checkout"
name="Checkouts"
res_model="library.checkout"
view_mode="tree,form,activity,calendar,graph,pivot" />
三·表單視圖結構
業務文檔視圖
# 業務應用中記錄的很多數據可以按紙質文檔那樣展示
# 視圖的基本框架:包含 form , header , sheet 和 mail
# header 狀態欄,
sheet主內容 ,
底部交流區 也稱作chatter,需要繼承mail.thread和mail.activity.mixin
<record id="view_form_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<form>
<header>
<!--以下僅供查看效果使用-->
<field name="state" widget="statusbar" clickable="True" />
</header>
<sheet>
...
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" />
<field name="activity_ids" widget="mail_activity" />
<field name="message_ids" widget="mail_thread" />
</div>
</form>
</field>
</record>
頭部header 通常用於文檔所走過的生命周期或步驟,還包含相關的操作按鈕。這些按鈕是普通表單按鈕,最重要的下一步可以高亮顯示。
頭部按鈕
<header>
<field name="state" invisible="True" />
<button name="button_done"
string="Return Books"
attrs="{'invisible':
[('state', 'in', ['new', 'done'])]}"
class="oe_highlight" />
</header>
# domain 或 attrs 表達式中使用的字段必須在視圖中加載,作用於它們的<field>元素。如果字段不對用戶可見,則必須以不可見字段元素對其進行加載。
#state字段, 相同的效果可以通過states字段屬性實現.雖然沒有attrs屬性靈活,states更為精簡
<button name="button_done"
type="object"
string="Returned"
states="open,cancel"
class="oe_highlight" />
# attrs和states元素可見功能也可用於其它視圖元素
階段管道
# 是statusbar組件的stage_id字段的<field>元素
# 通常狀態或者階段字段是一個many-to-on字段,允許使用者點擊,clickable屬性變更狀態.
# 也可將狀態隱藏折疊,通常命名為fold,然后statusbar組件使用options屬性來將這一字段名提供給fold_field
<header>
<field name="stage_id"
widget="statusbar"
clickable="True"
options="{'fold_field': 'fold'}" />
</header>
狀態代替階段
需要使用statusbar_visible屬性來替換fold_field選項
<field name="state"
widget="statusbar"
clickable="True"
statusbar_visible="draft,open,done" />
文檔表單
# 設計類似一張真實的紙質文檔,
# 包含:
左上角文檔標題和副標題
右上角按鈕區
其它文檔頭部字段
底部筆記區,將附加字段組織成選項卡或頁面
標題和副標題
# 一般標題放在oe_title類中。以下為擴展后的<sheet>元素,它包含標題以及一些額外字段如副標題
<field name="member_image" widget="image" class="oe_avatar" />
<div class="oe_title">
<label for="member_id" class="oe_edit_only" />
<h1><field name="member_id" /></h1>
<h3>
<span class="oe_read_only">By </span>
<label for="user_id" class="oe_edit_only" />
<field name="user_id" class="oe_inline" />
</h3>
</div>
<!-- More elements will be added from here... -->
</sheet>
表單內容分組
# 表單主內容區應通過<group>標簽來進行組織。
# <group>標簽在畫布中插入了兩列。
# 默認在這些列中標簽會在字段旁顯示,因此又占據兩列。
# 字段加標簽會占據 一行,下一個字段和標簽又會另起一行,垂直排列。
# Odoo表單的常見布局是帶標簽的字段並排成兩列。達到這一效果,我們只需要添加兩個嵌入頂部的<group>標簽。
<group name="group_top">
<group name="group_col1">
<field name="user_id" />
<field name="checkout_date" />
</group>
<group name="group_col2">
<field name="state" />
<field name="closed_date" />
</group>
</group>
選項卡筆記本(Tabbed notebooks)
# 組織內容的方式是 notebook 元素,一個包含多個稱為頁面(page)的選項卡分區的容器
# 它們可以讓不常用的內容在不使用時隱藏起來,或者用於按話題組織大量字段。
# page支持以下屬性:
string:選項卡的標題(必填)
attrs:不可見屬性與表達式映射的字典
accesskey:HTML訪問密鑰
<notebook>
<page string="Borrowed Books" name="page_lines">
<field name="line_ids" />
</page>
</notebook>
四·字段
# 視圖字段可用屬性
name # 標識字段數據庫中名稱
string # 用於想要覆蓋模型中標簽文本的標簽文本
help # 是鼠標懸停在字段上顯示的提示文本,它允許我們覆蓋模型定義中提供的幫助文本
placeholder # 是在字段中顯示的提示文本
widget # 讓我們可以覆蓋字段的默認組件,一會兒我們就會講到可用的組件
options # 是一個帶有組件附加數據的JSON數據結構,值隨各組件的不同支持而不同
class # 是用於字段 HTML 渲染的CSS類
nolabel=”True” # 阻止自動字段標簽的展示。僅對<group>元素內的字段有作用,通常與<label for=”…”>元素一起使用。
invisible=”True” # 讓字段不可見,但仍會從服務端獲取數據並可在表單中使用
readonly=”True” # 讓表單中該字段不可編輯
required=”True” # 讓表單中該字段為必填
password=”True” # 用於文本字段。顯示為密碼項,隱藏所輸入文字
filename # 用於二進制字段,它是用於存儲上傳文件名的模型字段的名稱
字段標簽
# <label>元素可用於更好地控制字段標簽的展示
# 例子:是僅在表單為編輯模式時展示
<label for="name" class="oe_edit_only" />
# 注意:在group元素內部,通常設置nolabel="True",class='oe_edit_only'的css樣式
字段組件
### 對於文本字段
mail # 用於讓 email 文本成為可操作的”mail-to”地址
url # 用於將文本格式化為可點擊的URL
html # 用於將文本渲染為HTML內容;在編輯模式下,它顯示為一個WYSIWYG(所見即所得)編輯器,可在不使用 HTML 代碼的情況下格式化內容。
### 對於數字字段,有以下組件:
handle # 在列表視圖中作為一個排序字段,顯示一個句柄來讓我們可以拖放進行自定義排序
float_time # 將一個浮點型字段格式化為帶有小時和分鍾的值
monetary # 將一個浮點型字段顯示為貨幣金額。它與currency_id字段一起使用,還可以通過options=”{‘currency_field’: ‘currency_id’}”來使用另一個字段名
progressbar # 將一個浮點值顯示為進度條百分比,有助於將字段展示為完成率
percentage和percentpie # 組件可用於浮點型字段
### 對於關聯和選擇項字段,有以下附加組件:
many2many_tags # 將值顯示為按鈕標簽列表
many2many_checkboxes # 將選項值顯示為一個復選框列表
selection對many-to-one # 字段使用選擇字段組件
radio # 以單選按鈕顯示選擇字段選項
priority # 將選項字段顯示為一個可點擊星形列表。選擇項目通常是數值。
state_selection # 將看板狀態選擇列表顯示為信號燈。普通狀態顯示為灰色,完成顯示為綠色,其它狀態顯示為紅色。
pdf_viewer # 是一個二進制字段(在 Odoo 12中引入)。
# state_selection在 Odoo11中引入來替換掉kanban_state_selection。后者被淘汰,但為保持向后兼容性,還支持使用。
關聯字段
# 默認用戶從這些字段中創建新記錄(也稱作“快速創建”)並打開關聯記錄表單。可通過options字段屬性來關閉:
options="{'no_open': True, 'no_create': True}"
# context和domain也是字段屬性並對於關聯字段特別有用
context可定義關聯字記錄默認值
domain 可限制可選記錄
# 如果想要在列表視圖的表單彈出窗口中直接編輯one-to-many路線,應使用<tree editable=”top”>或<tree editable=”bottom”>
五·按鈕
普通按鈕
# 按鈕支持的屬性
string # 是按鈕文本標簽或使用圖標時的 HTML alt 文本
type # 是執行操作的類型,有以下值:
object # 用於調用 Python 方法
action # 用於運行窗口操作
name # 標識按所選類型要操作的具體的操作,要么是模型方法名,要么是要運行的窗口操作的數據庫 ID。可使用%(xmlid)d方程式來將XML ID轉換成加載視圖時所需的數據庫 ID。
args在類型為 object 時用於向方法傳遞額外的參數,須是在形成方法調用參數的記錄 ID 之后所添加的純靜態 JSON 參數。
context # 在上下文中添加值,可在窗口操作或 Python 代碼方法調用之后產生效果。
confirm # 在運行相關操作之前顯示確認消息框,顯示的內容是屬性中分配的文本。special=”cancel”用於向導表單。
icon # 是按鈕所顯示的圖標。可用的按鈕來自Font Awesome圖標集,版本為4.7.0,應通過對應的 CSS 類來指定,如icon=”fa-question”。更多信息可訪問Font Awesome。
智能按鈕
# 智能按鈕(smart button) 智能按鈕顯示為帶有數據指示的矩形,在點擊時可進入
# 智能按鈕通常是sheet的第一個元素,且帶有oe_button_box樣式.
### 注意:
# 1. 智能按鈕必須帶有class=”oe_stat_button” CSS樣式,
# 2. 並應使用 icon 屬性來帶有一個圖標。
# 3. 它有一個type=”action”,表示點擊按鈕時將運行通過 name 屬性標識的窗口操作。%(action_other_checkouts_button)d表達式返回要運行的操作的數據庫 ID
### 智能按鈕屬性值:
class=”oe_stat_button” # 渲染的不是普通按鈕而是一個矩形
icon # 從Font Awesome圖標集中選擇圖標來使用。訪問Font Awesome查看有哪些圖標。
type和name # 是按鈕類型以及觸發的操作名。對於智能按鈕,類型通常是 action,指定窗口操作,名稱為所要執行操作的 ID。應傳入真實數據庫 ID,因此我們要使用方程式來將XML ID轉換為數據庫 ID:”%(actionxmlid)d”。這一操作應該會打開帶有關聯記錄的視圖。
string # 按鈕添加標簽文本,這里沒有使用因為所包含的字段中已經提供了文本。
context # 應用於為目標視圖設置默認值,用於點擊按鈕后視圖上新建的記錄。
help # 在鼠標懸停在按鈕上顯示幫助提示信息
num_other_checkouts = fields.Integer(compute='_compute_num_other_checkouts')
def _compute_num_other_checkouts(self):
for rec in self:
domain = [('member_id', '=', rec.member_id.id),
('state', 'in', ['open']),
('id', '!=', rec.id)]
rec.num_other_checkouts = self.search_count(domain)
<div name="button_box" class="oe_button_box">
<button class="oe_stat_button"
icon="fa-tasks"
help="Other checkouts pending return."
type="action"
name="%(action_other_checkouts_button)d"
context="{'default_member_id': member_id}">
<field string="To Return"
name="num_other_checkouts"
widget="statinfo" />
</button>
</div>
六·動態視圖元素
onchange 事件
# 通過@api.onchange('field1',...)裝飾器創建模型
# onchange 機制還可以在用戶輸入時即時反饋進行計算字段的自動重算
動態屬性
# 屬性允許根據記錄的值來動態變更視圖元素的顯示.
# groups 可根據當前用戶所屬安全組,讓元素課件. 指定僅該組員成員可看到元素.
# states 可以根據記錄的狀態字段來讓元素課件.
# 特別屬性 attrs ,值為一個映射invisible屬性值與表達式結果的字典.
例子: 要讓closed_date字段在new和open狀態時不可見
<field name="closed_date" attrs="{'invisible':[('state', 'in', ['new', 'open'])]}"/>
# 注意:
invisible不只在字段種可用,任意元素種均可使用.如notebook頁面和group元素.attrs屬性可以設置兩個屬性值:readonly和required.
七·列表視圖
# tree元素的相關屬性
# default_order讓我們可以覆蓋模型中的默認排序,它的值和模型中定義的排序格式相同。
# create, delete和edit,如果設為 false(字母小寫),會禁用列表視圖中的相應操作。
# editable讓記錄在列表視圖中可直接被編輯。可用值有 top 和 bottom,表示新記錄添加的位置。
# 數值字段可顯示為對應列的匯總值。為字段添加一個累加屬性(sum, avg, min或max)會為其分配匯總值的標簽文本
<record id="view_tree_checkout" model="ir.ui.view">
<field name="name">Checkout Tree</field>
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<tree
decoration-muted="state in ['done', 'cancel']"
decoration-bf="state=='open'">
<field name="state" invisible="True" />
<field name="request_date" />
<field name="member_id" />
<field name="checkout_date" />
<field name="stage_id" />
<field name="num_books" sum="# Books" />
</tree>
</field>
</record>
num_books = fields.Integer(compute='_compute_num_books')
@api.depends('line_ids')
def _compute_num_books(self):
for book in self:
book.num_books = len(book.line_ids)
八·搜索視圖
#
# 這兩個過濾器可以分別被啟用並以 OR運算符連接。以<separator />元素分隔的整塊過濾器以 AND 運算符連接
# 第三個過濾器僅設置 group by 上下文鍵,它讓視圖按照字段來對記錄分組
#字段屬性:
# name 標識字段
# string 標簽文本,替換默認值
# operator 修改默認的預算符
# filter_domain 設置搜索使用的特定域表達式,為operator提供靈活的替代方式. 例如:filter_domain=”[(‘name’, ‘ilike’, self)]”
# groups 對該字段的搜索僅向安全組內成員開發,值是一個逗號分隔的xmlid列表
# 過濾元素屬性
# name 用作后續繼承/擴展或通過窗口操作啟用的標識符。這不是必填項,但包含該屬性是一個不錯的編碼習慣。
# string 是過濾器顯示的標簽文本,必填
# domain 是加入當前域的域表達式
# context 是加入當前上下文的上下文字典。通常使用group_id作為鍵,用於對記錄分組的字段名作為值
# groups 讓該字段的搜索僅對安全組列表(XML IDs)成員開放
<record id="view_filter_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<search>
<field name="member_id" />
<field name="user_id" />
<filter name="filter_not_done"
string="To Return"
domain="[('state','=','open')]" />
<filter name="filter_my_checkouts"
string="My Checkouts"
domain="['user_id', '=', uid]" />
<filter name="group_user"
string="By Member"
context="{'group_by': 'member_id'}" />
</search>
</field>
</record>
九·其它視圖類型
# 其他視圖類型:
activity # 將計划活動顯示為有組織的匯總
calendar # 基於所選日期字段以日歷格式展示數據
diagram # 展示記錄間的關系,當前不在 Odoo 中使用
# 兩種視圖類型用於顯示累加數據
graph # 用於圖表展示
pivot # 用於交互的數據透視表
# Odoo 企業版中可用
dashboard # 使用透視表和圖表這類子視圖展示累加數據
cohort # 用於顯示在不同時期數據如何變化
gantt # 以甘特圖顯示日期計划信息,常用於項目管理
grid # 通過行和列網格組織數據進行展示
活動視圖
# 由mail模塊提供. 用於可視化活動任務
<activity string='Activities' />
日歷視圖
# 在日歷種展示記錄,按照不同的時間區間.
# 屬性:
date_start 開始日期 必填
date_end 結束日期 選填
date_delay 天數字段,用於替代date_end
all_day 傳入一個布爾字段名,標識全天活動
color 用於日歷添加顏色
mode 日歷視圖默認顯示模塊,
<record id="view_calendar_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<calendar date_start="request_date"
color="user_id">
<field name="member_id" />
<field name="stage_id" />
</calendar>
</field>
</record>

透視表視圖
# 透視表 是動態分析矩陣
# 累加數據僅對數據庫種存儲的字段有效.
# 比如:
num_books = fields.Integer(compute='_compute_num_books',store=True)
# name像其它視圖一樣標識圖標種的字段
# type是指如何使用字段,行分組(默認)、度量(measure)或列(僅針對透視表,用於列分組)
# interval用於日期字段,是對時間數據的分組間隔:按天、按周、按月、按季度或按年
<record id="view_pivot_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<pivot>
<field name="stage_id" type="col" />
<field name="member_id" />
<field name="request_date" interval="week" />
<field name="num_books" type="measure" />
</pivot>
</field>
</record>

圖表視圖
# 圖表視圖將數據累加展示圖表. 可以使柱狀圖,線狀圖和餅圖
# type屬性,值可為 bar(默認), pie或line
# type=”row”是默認值,設置累加值的條件
# type=”measure”用於作為實際累加值的度量字段
<record id="view_graph_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<graph type="bar">
<field name="stage_id" />
<field name="num_books" type="measure" />
</graph>
</field>
</record>
