一 odoo动作一览图
二 动作分类
窗口动作(ir.actions.act_window )
最常用的action类型,用于打开模型的各种视图。
定义方式一:
<act_window
id="act_bangumi_view"
name="Bangumi"
res_model="bangumi.bangumi" # 需要在view里显示数据的model。
view_mode="tree,kanban,form"
view_id="view_bangumi_bangumi_list" # 数据库视图记录id或False,如果没有指定id,客户端会自动用fields_view_get()获取相应类型的默认视图。
/>
定义方式二:
<record id="act_bangumi_view" model="ir.actions.act_window">
<field name="name">Bangumi</field>
<field name="res_model">bangumi.bangumi</field>
<field name="view_mode">tree,kanban,form</field>
<field name="view_id" ref="view_bangumi_bangumi_list"/>
</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
<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中)动作:
用法举例:
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)
用法举例:
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)定义报表视图
<?xml version="1.0" encoding="utf-8"?>
<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();})