一些使用者介面
資料檔案 (XML)
參考: 該主題關聯文件可以檢視Data Files.
上一章,我們透過CSV檔案新增了資料。當需要新增資料格式簡單時,用CSV格式還是很方便的,當資料格式更復雜時(比如檢視架構或者一個郵件模板),我們使用XML格式。比如包含HTML tags的 help field。雖然可以透過CSV檔案載入這樣的資料,但是使用XML更方便。
類似CSV檔案,XML檔案也必須按約定新增到合適的目錄,並在 __manifest__.py
中進行定義。資料檔案中的內容也是在模組安裝或者更新時按序載入。因此,對CSV檔案所做的所有說明對XML檔案都適用。當資料連結到檢視時,我們將它們新增到views
資料夾中
本章,我們將透過XML檔案載入我們第一個action和選單。Actions 和選單為資料庫中的標準記錄。
註解:
當程式很注重效能時,CSV格式優先於XML格式。這是因為,在odoo中載入CSV檔案比載入XML檔案更快。
odoo中,使用者介面(action,選單和檢視)大部分是透過建立和組裝XML檔案中的記錄來定義的。常見的模式為 選單> action > 檢視。為了訪問記錄,使用者在幾個選單級中導航。最深層是觸發開啟記錄列表的action。
操作(Actions)
參考: 主題相關文件可以檢視 Actions.
動作可以透過三種方式觸發 :
- 點選選單專案(連結接到指定動作)
- 點選檢視按鈕(如果與action關聯)
- 物件的上下文action
本章僅涵蓋第一種情況。 我們Real Estate例子中,希望將一個選單連線到 estate.property
model, 以便建立一個新記錄。 action可以視為選單和model之間的連結
test.model
的基本action:
<record id="test_model_action" model="ir.actions.act_window">
<field name="name">Test action</field>
<field name="res_model">test.model</field>
<field name="view_mode">tree,form</field>
</record>
id
外部標識。它可以用於引用記錄(不需要知道其在資料庫中的識別符號)。model
ir.actions.act_window
(Window Actions (ir.actions.act_window))的一個固定值name
action名稱res_model
action應用的範圍。view_mode
可獲取的檢視。本例中為列表(樹)和表格檢視。
odoo中到處都可以找到例子,但是這個 簡單action的好例子。關注XML 資料檔案結構,因為你在後續的練習中會用到。
<?xml version="1.0"?>
<odoo>
<record id="crm_lost_reason_view_search" model="ir.ui.view">
<field name="name">crm.lost.reason.view.search</field>
<field name="model">crm.lost.reason</field>
<field name="arch" type="xml">
<search string="Search Opportunities">
<field name="name"/>
<filter string="Include archived" name="archived" domain="['|', ('active', '=', True), ('active', '=', False)]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
</search>
</field>
</record>
<record id="crm_lost_reason_view_form" model="ir.ui.view">
<field name="name">crm.lost.reason.form</field>
<field name="model">crm.lost.reason</field>
<field name="arch" type="xml">
<form string="Lost Reason">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_lost_leads" type="object"
class="oe_stat_button" icon="fa-star">
<div class="o_stat_info">
<field name="leads_count" class="o_stat_value"/>
<span class="o_stat_text"> Leads</span>
</div>
</button>
</div>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name"/>
</div>
<h1 class="mb32">
<field name="name" class="mb16"/>
</h1>
<field name="active" invisible="1"/>
</div>
</sheet>
</form>
</field>
</record>
<record id="crm_lost_reason_view_tree" model="ir.ui.view">
<field name="name">crm.lost.reason.tree</field>
<field name="model">crm.lost.reason</field>
<field name="arch" type="xml">
<tree string="Channel" editable="bottom">
<field name="name"/>
</tree>
</field>
</record>
<!-- Configuration/Lead & Opportunities/Lost Reasons Menu -->
<record id="crm_lost_reason_action" model="ir.actions.act_window">
<field name="name">Lost Reasons</field>
<field name="res_model">crm.lost.reason</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Define a new lost reason
</p><p>
Use lost reasons to explain why an opportunity is lost.
</p><p>
Some examples of lost reasons: "We don't have people/skill", "Price too high"
</p>
</field>
</record>
<record id="menu_crm_lost_reason" model="ir.ui.menu">
<field name="action" ref="crm.crm_lost_reason_action"/>
</record>
</odoo>
練習
為 estate.property
model 建立action。
在適當的位置(本例中為odoo14/custom/estate/models/views
)建立 estate_property_views.xml
<?xml version="1.0"?>
<odoo>
<record id="link_estate_property_action" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>
修改odoo14/custom/estate/__manifest__.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
'name': 'estate',
'depends': ['base'],
'data':['security/ir.model.access.csv',
'views/estate_property_views.xml'
]
}
重啟服務並觀察檔案載入日誌。
選單(Menus)
參考: 和本主題關聯文件可以檢視Shortcuts.
為了減少選單(ir.ui.menu
)定義和連結到對應action的複雜性,我們可以使用 shortcut
test_model_action
一個的基礎選單:
<menuitem id="test_model_menu_action" action="test_model_action"/>
test_model_menu_action
選單被連結到 test_model_action
,action
連結到model test.model
。正如前面所述, action
可以看做是選單和model
之間的連線。
注意:這裡的id的值和action的值不能設定成一樣,否則會報錯。
然而,選單總是遵循一種體系結構,實際上有三個層次的選單:
- 根選單,顯示在App切換器中(Odoo社群版切換器是一個下拉選單)
- 第一級選單,顯示在頂部欄中
- 動作選單
最容易的方式是在XML檔案中定義結構來建立選單。
為 test_model_action
定義的一個基礎選單結構:
<menuitem id="test_menu_root" name="Test">
<menuitem id="test_first_level_menu" name="First Level">
<menuitem id="test_model_menu_action" action="test_model_action"/>
</menuitem>
</menuitem>
第三級選單的名稱,直接從action
獲取,即為action
屬性值
練習
新增選單
在合適的目錄(本例中為odoo14/custom/estate/models/views
)建立 estate_menus.xml
檔案
<?xml version="1.0"?>
<odoo>
<menuitem id="test_menu_root" name="Test">
<menuitem id="test_first_level_menu" name="First Level">
<menuitem id="estate_property_menu_action" action="link_estate_property_action"/>
</menuitem>
</menuitem>
</odoo>
修改odoo14/custom/estate/__manifest__.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
'name': 'estate',
'depends': ['base'],
'data':['security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_menus.xml'
]
}
重啟odoo服務,檢視效果
欄位,屬性和檢視(Fields, Attributes And View)
到目前為止,我們只對房產廣告使用了通用檢視,但在大多數情況下,我們希望對檢視進行微調。Odoo有許多微調方式,但通常第一步是確保:
- 某些欄位有預設值
- 某些欄位只讀
- 當記錄重複時,某些欄位不能被複製
在我們的房產業務案例中,我們希望::
- 售價只讀(往後將自動填充)
- 當記錄重複時,可用日期和售價不能被複製
- 臥室數量應該預設為2
- 預設可用日期應該為3個月
一些新屬性
在進一步進行檢視設計之前,讓我們回到模型定義。我們看到一些屬性,如required=True
,會影響資料庫中的表模式。其他屬性也將影響檢視或提供預設值。
練習 -- 新增一些屬性到欄位。
查詢一些合適的屬性 (檢視欄位
) 來:
- 設定售價為只讀
- 阻止複製可用日期和售價
修改 odoo14\custom\estate\models\estate_property.py
中EstateProperty
類屬性expected_price
,selling_price
的值如下:
expected_price = fields.Float('expected price', digits=(8, 2), required=True)
selling_price = fields.Float('selling price', digits=(8, 2), readonly=True, copy=False)
重啟服務和並重新整理瀏覽器介面,我們可以看到無法設定任何售價。複製記錄時,可用日期應為空。
預期效果可參考該動畫連線:https://www.odoo.com/documentation/14.0/zh_CN/_images/attribute_and_default.gif
預設值
可以為任何欄位設定預設值。欄位定義中,新增 default=X
, 其中的X
可以是Python文字值(boolean, integer, float, string) ,也可以是一個以model物件自身為入參並返回一個值的函式:
name = fields.Char(default="Unknown")
last_seen = fields.Datetime("Last Seen", default=lambda self: fields.Datetime.now())
例中name
欄位預設值為‘Unknown’,而last_seen
欄位預設值為當前時間
練習 -- 設定預設值
新增適當的預設值:
- 臥室數量預設值為 2
- 可用日期預設為3個月內
修改 odoo14\custom\estate\models\estate_property.py
中EstateProperty
類屬性bedrooms
,selling_price
的值如下:
bedrooms = fields.Integer(default=2)
date_availability = fields.Datetime('Availability Date', copy=False, default= lambda self: fields.Datetime.today())
重啟服務和並重新整理瀏覽器介面驗證
保留欄位
參考: 主題相關文件可參考 保留欄位名稱.
odoo為預定義行為保留了一些欄位名稱。當需要相關行為時,需要在模型中定義這些保留欄位。
練習 -- 新增active
欄位
新增一個 active
欄位到estate.property
模型。
修改 odoo14\custom\estate\models\estate_property.py
中EstateProperty
類,增加active
屬性
active = fields.Boolean('Active')
重啟服務,重新整理瀏覽器介面,新增一條記錄,新增時勾選Active
核取方塊,即active=True
,驗證效果。
預期效果可參考該動畫連結:https://www.odoo.com/documentation/14.0/zh_CN/_images/inactive.gif
注意,已存在的記錄的active
欄位預設值為False
練習--為active
欄位新增設定
為active
欄位設定預設值
為 active
欄位設定適當的屬性值,讓它不再出現在頁面。
練習 -- 新增state
欄位
為estate.property
model新增state
欄位(欄位名可自定義),一個選擇列表。可選值: New, Offer Received, Offer Accepted, Sold 和Canceled。必選欄位,且不能被複製,預設值New
修改 odoo14\custom\estate\models\estate_property.py
中EstateProperty
類,修改active
欄位,增加state
欄位
active = fields.Boolean('Active', default=True, invisible=True) # 注意:實踐發現,invisible欄位不起作用
state = fields.Selection(
string='State',
selection=[('New','New'),
('Offer Received','Offer Received'),
('Offer Accepted', 'Offer Accepted'),
('Sold','Sold'),
('Canceled', 'Canceled')],
copy=False
)
重啟服務,驗證效果