一些用戶界面 數據文件 (XML) 參考: 該主題關聯文檔可以查看Data Files. 上一章,我們通過CSV文件添加了數據。當需要添加數據格式簡單時,用CSV格式還是很方便的,當數據格式更複雜時(比如視圖架構或者一個郵件模板),我們使用XML格式。比如包含HTML tags的 help fiel ...
一些用戶界面
數據文件 (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
)
重啟服務,驗證效果
作者:授客
微信/QQ:1033553122
全國軟體測試QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限於時間倉促,文中可能存在錯誤,歡迎指正、評論!
作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額隨意,您的支持將是我繼續創作的源動力,打賞後如有任何疑問,請聯繫我!!!
微信打賞
支付寶打賞 全國軟體測試交流QQ群