Odoo中的五種action都是繼承自ir.actions.actions模型實現的子類,共有五種。分別對應五種類型、五種用途。
odoo中還有其他含有action命名的模型,諸如:action.todo等,都不是actions的子類,不是動作;
odoo中翻譯為動作的,也不全是action,例如:自動動作,它是ir.cron模型,執行服務器的定時任務。
一:窗口action(ir.actions.act_window )
最常用的action類型,用於打開模型的各種視圖。
字段列表:
1:res_model
需要在view里顯示數據的model。
2:view_type
代表視圖類型如:form,tree,gragh...,type參數列表的第一個會被默認用來展示。
3:view_id
數據庫視圖記錄id或False,如果沒有指定id,客戶端會自動用fields_view_get()獲取相應類型的默認視圖。
4:res_id (可選)
當默認的視圖類型是form,並且模型定義了不止一個form視圖時,可用red_id字段指定加載具體的form視圖id
5:search_view_id (可選)
(id, name),id是儲存在數據庫的搜索視圖id,默認會讀取model的默認搜索視圖
6:target (可選)
定義視圖打開模式 在當前視圖上打開(current)、使用全屏模式(fullscreen)、新窗口打開(new),可使用main代替current來清除面包屑導航[面包屑導航:讓用戶了解目前所處位置,以及當前頁面在整個網站中的位置]
7:context (可選)
額外的需要傳給要打開的視圖的環境數據。
-
1)模型有多個同種視圖時,指定打開具體的視圖
-
<field name="context">{'tree_view_ref':'模塊.view_tree_XXX','form_view_ref':'模塊.view_form_XXX'}</field>
-
<field name="search_view_id" ref="view_search_XXX/>
-
-
2)在跳轉的同時啟用過濾器
-
<field name="context">{'search_default_過濾器名': [active_id]/True}</field>
-
-
3)傳遞數據,可用於domain中作為表達式的值
-
<field name="context">{"key":value}</field>
-
-
4)指定跳轉過去的視圖記錄的分組方式
-
<field name="context">{'group_by': ['字段','...'];'group_by_no_leaf':1}</field>
8:domain (可選)
自動添加到搜索視圖中的查詢條件,即:跳轉到目標視圖時,立即應用domain條件過濾模型記錄。
表達式中的值可以是具體的常量值,也可以是調用該action時傳進來的context中的變量值。
<field name="domain">[('字段', '=', '具體值'),('字段','=',上下文中的變量)]</field>
context中的變量值有兩種方式指定:
1)在python代碼中調用action
-
ctx = self._context.copy()
-
ctx.update({
-
'key': 值,
-
})
-
[action] = self.env.ref(action_name).read()
-
action['context'] = ctx
-
return action
2)在action的context字段直接指定,不過一般都是明確的字面量值
-
//傳遞數據
-
<field name="context">{"key":value}</field>
9:limit (可選)
在客戶端顯示的數據量,默認為80條。
10:auto_search(可選)
是否在加載默認視圖后立即執行搜索,默認True
11:view_mode
以逗號分隔的視圖類型列表,所有列舉的類型的視圖記錄都會被加載。
12:view_ids
一般用於具體指定view_mode中列舉類型的各種視圖的具體記錄。用法如下:
-
<record id="action_" model="ir.actions.act_window">
-
<field name="view_ids" eval="[(5,0,0),
-
(0,0,{'view_mode':'tree'}),
-
(0,0,{'view_mode':'form', 'view_id': ref('form視圖id')})]"/>
-
</record>
二:鏈接Action(ir.actions.act_url)
可以通過odoo的鏈接打開一個網站頁面,可通過兩個字段來自定義:
- url -- 激活action時所打開的鏈接
- target -- new:在新窗口打開,self:替換當前頁面內容,默認new
用法:
1)視圖上:通過點擊菜單,打開鏈接
-
<record id="url_action_XXX" model="ir.actions.act_url">
-
<field name="name"></field>
-
<field name="url">網址</field>
-
<field name="target">new</field>
-
</record>
-
<record id="base.open_menu" model="ir.actions.todo">
-
<field name="action_id" ref="url_action_XXX"/>
-
<field name="state">open</field>
-
</record>
2)python代碼:可以作為按鈕的點擊函數,在函數中return一個鏈接action,打開鏈接
-
return {
-
'type': 'ir.actions.act_url',
-
'url': 鏈接,
-
'target': 'self',
-
'res_id': self.id,
-
}
三:服務器Action (ir.actions.server)
可以通過服務器action來觸發復雜的服務端動作:
-
- id -- 服務器action在數據庫存儲的id
-
context (可選) -- 額外的傳遞給服務器action作用目標的數據
-
model_id -- 與action相關聯的model
- condition (可選) -- 使用服務端的 evaluation contexts 來執行python代碼,如果是False則阻止action執行,默認值是True
- code -- 當調用action時執行的python代碼
-
-
object_create -- 使用鈎子創建一條新記錄(通過調用模型的create或copy方法)
-
use_create
1.new - 基於指定的 model_id創建一條記錄
2.new_other - 基於指定的crud_model_id創建一條記錄
3.copy_current - 復制action所引用的記錄
4.copy_other - 復制一個通過ref_object獲得的記錄 -
fields_lines --當創建或復制記錄時需要修改的字段,One2many 會有以下字段:
1.col1 -- 在use_create里所包含的需要被重賦值的ir.model.fields
2.value -- 字段對應的值,基於type進行解析
3.type -- 取值value:就是value字段的值,取值equation:value字段會當成python來解析 - crud_model_id -- 當use_create為new_other時,表示用於創建新記錄的model id
- ref_object -- 當use_create為copy_other時用於指定創建記錄時引用的記錄
- link_new_record -- 是否用用link_field_id將新記錄和當前記錄進行many2one關聯,默認False
- link_field_id -- 指定當前記錄與新記錄進行many2one關聯的字段
-
-
object_write -- 與object_create相似,不同的是 只修改當前記錄而不創建新記錄
- use_create
1.current - 修改更新到當前記錄
2.other - 修改更新到通過crud_model_id 或 ref_object指定的新記錄
3.expression - 修改更新到通過crud_model_id 以及 write_expression篩選過后的記錄 - write_expression - 返回一條記錄或對象id的python表達式
- fields_lines,crud_model_id,ref_object與object_create一致
- use_create
-
multi
將通過child_ids many2many關系定義的action一個個執行,如果有action自己返回action,最后一個action被返回給客戶端作為將前multi action的下一個action -
trigger 發送一個信號給工作流
- wkf_transition_id - 用於觸發的與workflow.transition有Many2one關系的id
- use_relational_model - 如果是base(默認),則觸發當前記錄的維護信號;如果是relational,則觸發通過wkf_model_id 和 wkf_field_id篩選出來的當前記錄的字段
-
client_action -- 返回通過action_id定義的action
-
用法舉例:
-
//定義action
-
<record model="ir.actions.server" id="記錄id">
-
<field name="name"></field>
-
<field name="type">ir.actions.server</field>
-
<field name="model_id" ref="模塊名.model_下划線分隔的模型名"/>
-
<field name="code">
-
要執行的python代碼。
-
</field>
-
</record>
-
-
//調用action
-
1)可以在界面上調用,作為按鈕點擊事件等
-
<button name="%(模塊名.action記錄id)d" type="action" string="按鈕文本" class="oe_link"/>
-
-
2)也可以在python代碼中使用
-
-
3)結合odoo中的定時任務使用
四:客戶端Actions (ir.actions.client)
觸發一個在客戶端實現(即js文件中定義的函數,通過core.action_registry.add(tag,函數名) 注冊到odoo中)動作:
-
- tag -- action在客戶端的標識符,一般是一個專用的字符串,在js文件中注冊該動作時指定。
- params (可選) -- 用來傳給客戶端動作的,字典格式
- target (可選) -- current:當前內容區打開action;fullscreen:以全屏模式打開;new:以新窗口打開。
- context-- 作為額外數據,傳遞給客戶端函數。
用法舉例:
1)在js文件中定義客戶端widget,並注冊
-
var 自定義widget名= Widget.extend({
-
init:init函數;
-
start:自動調用到start函數;
-
其他函數,被init、start調用。//自定義widget,就是自定義動作
-
})
-
-
core.action_registry.add('widget tag名', widget名);
-
-
return {
-
widget名: widget名,
-
};
2)在視圖中調用:作為按鈕的點擊函數的name屬性、作為菜單項的action
-
<record id="action_" model="ir.actions.client">
-
<field name="name"></field>
-
<field name="res_model"></field>
-
<field name="tag">widget注冊時的tag名</field>
-
</record>
3)在代碼中調用
-
return {
-
'type': 'ir.actions.client',
-
'name': '',
-
'tag': '動作的tag',
-
'params': {key:value},
-
}
【客戶端動作十分強大而且自由,可以在js文件中使用前端邏輯定義一系列操作,諸如跳轉、加載頁面等等都可以。甚至,可以加載自定義的qweb頁面進來,使用jinja填充數據,實現自由前端。】
五:報表渲染設置Action (ir.actions.report.xml)
此action用於在報表渲染前進行一些前置設定,如紙張大小、輸出文件名等等:
- name(必選) -- 在一個列表里進行查找時使用
- model (必選) -- 報表所反映的數據來源model
- report_type (必選) -- qweb-pdf | qweb-html
- report_name -- 報表命名,用於輸出的pdf文件名
- groups_id -- 可以讀取或使用當前報表的用戶組,Many2many字段
- paperformat_id -- 報表所使用的紙張格式,默認使用公司的格式,Many2one字段
- attachment_use -- 當取值true的時候只在第一次請求時生成報表,之后直接從保存的報表打印,可用於生成后不會有改變的報表
- attachment -- 使用python表達式來定義報表名字,該記錄可用變量object訪問
用法舉例:
1)定義報表模型
-
class XXXReport(models.AbstractModel):
-
_name = 'report.模塊名.報表名'
-
-
@api.model
-
def get_data(self, 參數):
-
獲取報表所需數據並返回。
-
-
@api.multi
-
def render_html(self, docids, data=None):
-
data = dict(data or {})
-
data.update(get_data(參數))
-
return self.env['report'].render('模塊名.報表qweb文件template id', data)//傳遞data,渲染報表
2)定義報表視圖
-
-
<odoo>
-
<data>
-
<template id="報表模板id">
-
Qweb語法,定義報表格式。
-
</template>
-
</data>
-
</odoo>
3)定義報表打印action
-
<record id="" model="ir.actions.report.xml">
-
<field name="name"></field>
-
<field name="model">report.模塊名.報表模型名</field>
-
<field name="report_type">qweb-pdf|qweb-html</field>
-
<field name="report_name">輸出的報表文件名</field>
-
</record>
4)在controller、按鈕事件等地方,渲染報表【渲染時,會自動調用渲染action,按照action指定的紙張格式、輸出文件名等設定進行渲染】
-
@http.route('/模塊/xx_report', type='http', auth='user')
-
def print_xx_report(self, 查詢條件值, **kw):
-
report_model = request.env['report.報表模型名'] //獲取報表模型
-
pdf = request.env['report'].with_context(查詢參數 = 查詢條件值).get_pdf(report_model, '模塊.報表qweb文件的template id')
-
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
-
return request.make_response(pdf, headers=pdfhttpheaders)
注:我們創建的報表,都是report模型中的一條記錄而已。
因此,odoo報表打印其實就是report模型的兩個方法:get_pdf(具體報表模型,報表視圖模板id) 和 get_html(具體報表模型,報表視圖模板id)。
因此,報表打印可以通過以上兩個方法,可以在任何地方觸發打印:在controller可以生成報表回傳(如上)、也可以作為按鈕的點擊函數進行響應。
此外,report模型還提供了render方法,傳遞參數進來直接渲染報表的qweb文件,也是可以的。
return self.env['report'].render('模塊.報表template id', data)
5)報表的打印
上面四步只是生成了報表,但是要調起打印機打印,報表工作才算是完成。
PDF報表:由於生成了PDF文件,任何PDF閱讀器都集成了打印選項,因此這不需要我們實現。
Html報表:網頁渲染的報表,因為整個網頁就是報表內容,因此打印報表就是打印網頁。
a)可以直接點擊瀏覽器的“打印”菜單,進行打印;
b)在報表頁面,設置一個botton,為它指定響應事件,調用瀏覽器的打印函數
$('.print_button').click(function() {window.print();})