Odoo中Qweb使用入门
参考
可参考官网例子https://doc.odoo.com/trunk/web/qweb/或
http://thierry-godin.developpez.com/openerp/tutorial-module-creation-pos-modification-english-version/
1 Qweb官方定义
Qweb被用作OpenERP的Web客户端模板引擎。它是一种基于XML的模板语言,同Genshi, Thymeleaf、Facelets模板具有相似并且具有以下特性:
完全在客户端浏览器中完成渲染;
一个模板文件中可以包含多个模板,通常一个模板文件中包含一个模板;
对OpenERP的web组件有很好的支持,也可以用于除开OpenERP web外的其他框架。
2 OpenERP中使用Qweb
2.1 获取Odoo中由Bazaar管理的Qweb例子源代码
bzr branch lp:~niv-openerp/+junk/oepetstore -r 1-Ossl.cert_reqs=none
从python安装路劲下的Script目录中复制项目oepetstore到OpenERP的插件(addons)目录下,启动OpenERP,更新并安装oepetstore模块:
完成后在Chrome浏览器下访问http://localhost:8069/ 依次点击菜单:Pet Store àHome Page
点击无效,系统会提示。
这是由于定义在__openerp__.py文件中定义模块需要加载的petstore.js没被引用到系统。
暂时没找到原因,我用的是odoo_8.0rc1-latest版本,不知道是不是版本从7升级到8后的变化,解决方法:
在模块目录下建立xml文件(名称可随便取如link.xml),通过指定路劲引入js和css,
然后修改模块定义中data内容增加link.xml引用。(至于js和css此处没有生效,可去掉里面的引用)。
link.xml 内容:
<?xml version="1.0"encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<template id="assets_backend" name="petstore" inherit_id="web.assets_backend">
<xpath expr="."position="inside">
<link rel="stylesheet" href="/oepetstore/static/src/css/petstore.css"/>
<script type="text/javascript"src="/oepetstore/static/src/js/petstore.js"></script>
</xpath>
</template>
</data>
</openerp>
完成后重启系统,升级模块,再次点击菜单:Pet Store àHomePage ,在控制台下出现“petstore home page loaded”则表示模块已经运行成功:
到此Qweb还没开始使用,这仅仅是通过odoo的简单的应用了Widget组件。
官方对Widget定义,参考:https://doc.odoo.com/trunk/web/widget/
class openerp.web.Widget()
这是odoo中所有的可视化组件的基类。它对应于一个MVC视图。它处理部分的网页提供一系列的服务:
通过Qweb进行渲染;
继承关系;
生命周期管理(包括当父对象被删除子类的摧毁);
DOM文档插入操作,通过jQuery插入方法。插入对象可以是任何相应的jQuery方法(一般选择器,DOM节点和jQuery对象)。
2.2 通过Qweb结合Widget组件运用
目标:
点击左侧菜单,查询模块例子中表message_of_the_day的数据,通过Qweb以列表形式呈现。
(通过例子中自带的菜单添加一些假数据)
2.2.1 编写js代码
在static/src/js/petstore.js中添加
// MessageListPage部件扩展自Widget基类
instance.oepetstore.MessageListPage = instance.web.Widget.extend({
template: "message",//模板根节点(同xml模板文件中对应)
init: function() {
this._super.apply(this, arguments);
},
start: function() {
var self = this;
//message_of_the_day 表对应的模块名称
//query加上字段查询指定列,不加可以查询所有列
// query().all()查询所有数据
//query().first()查询第一条
new instance.web.Model("message_of_the_day").query(["message","create_date"]).all().then(function(result) {
var ss= result.message + result.create_date
//messageList 把得到的result josn数组,通过Qweb标签解析到名称为messageList(同xml模板文件中对应)的模板,模板标签对msgList进行遍历
self.$el.append($(QWeb.render("messageList",{msgList: result})));
$(".button-view").click(function(e){
alert("view..");
});
$(".button-edit").click(function(e){
alert("edit..");
});
$(".button-cancel").click(function(e){
alert("cancel..");
});
});
},
});
instance.web.client_actions.add('petstore.messagemenu','instance.oepetstore.MessageListPage');
2.2.2编写xml模板文件
static/src/xml/message.xml
<?xml version="1.0"encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="message">
<div class="oe_petstore_pettoyslist">
</div>
</t>
<t t-name="messageList">
<table class="oe_list_content">
<thead>
<tr>
<th class="oe_list_header_textoe_sortable">消息</th>
<th class="oe_list_header_textoe_sortable">创建时间</th>
<th>操作</th>
</tr>
</thead>
<t t-foreach="msgList"t-as="bo">
<tr class="oe_list_header_columns">
<td class="oe_list_field_celloe_list_field_text" ><t t-esc="bo.message"/></td>
<td class="oe_list_field_celloe_list_field_text" ><t t-esc="bo.create_date"/></td>
<td>
<a class="button-view" t-att-data="bo.id" name="detailBtn"href="#" ><i class="icon-zoom-in"></i>详情</a>
<a class="button-edit" t-att-data="bo.id" name="traceOrderBtn" href="javascript:void(0);"><iclass="fa fa-pencil"></i>编辑</a>
<a class="button-cancel" t-att-data="bo.id" class="red"name="cancelOrderBtn" href="javascript:void(0);"><i class="glyphicon glyphicon-remove"></i>取消</a>
</td>
</tr>
</t>
</table>
</t>
</templates>
此处我添加了一些odoo自带的css样式,在每列数据后面添加了几个可以操作的按钮(此处按钮功能未实现,仅提供样式)
2.2.3 在模块跟路径下petstore.xml中添加菜单链接和动作
<record id="message_day_action"model="ir.actions.client">
<field name="name">信息列表</field>
<field name="tag">petstore.messagemenu</field>
</record>
<menuitem id="message_day_action_menu"name="QwebMessageList" parent="petstore_menu" action="message_day_action"/>
通过Qweb对数据简单列表查询已经完成,重启Odoo,升级模块,依次点击菜单Pet Store àQwebMessageList,结果如下:
小提示:
1、一个模块中
openerp.oepetstore = function(instance) {
}该函数实例只能定义一个,并且为openerp.模块名称(必须跟模块名称一样,否则该js不能正确的被引入)
2、static目录下定义的js、css和xml模板改变了模块不需升级。
2.3关键点说明
2.3.1 QWeb模板引擎
QWeb模板在XML属性上加前缀“t-”表示:
t-name:模板名称,如:
<t t-name="message"></t>
t-foreach=iterable:循环遍历标签
<tt-foreach="msgList" t-as="bo"> </t>
t-esc:引用实例参数,可以使用任意JavaScript表达式;如
<tt-esc="bo.message"/>
t-att-attName:对象属性设置,如对input输入控件设置value:
<inputtype="text" t-att-value="order.buyer_memo"/>
其他更多标签可以参考https://doc.odoo.com/trunk/web/qweb/下 Defining Templates 节点
2.3.2 与服务器的交互-读取数据 (call 和query)
客户端使用Ajax与服务器交互,不过OpenERP框架提供了简化的方法,通过数据模型进行访问。OpenERP自动将服务端的数据模型转化为客户端端模型,直接调用即可。服务器上petstore.py里面的模型
call()方法应用:
客户端调用:
instance.oepetstore.HomePage =instance.web.Widget.extend({
start: function() {
var self = this;
var model = new instance.web.Model("message_of_the_day");
model.call("my_method",[],{context:newinstance.web.CompoundContext()}).then(function(result) {
self.$el.append("<div>Hello " +result["hello"] + "</div>");
});//通过读取到服务端数据展示在页面。
},
});
模型的call()方法参数:
第一个参数name是方法的名称;
第二个参数args是按照顺序排列的参数数组。OpenERP定义的模型方法前三个参数(self, cr, uid)是固定的,由框架产生,也就是说传递的参数数组从第四个开始插入。而context又是特殊的。
例子:方法定义:
def my_method2(self, cr, uid, a, b, c,context=None):
调用:
model.call("my_method", [1, 2,3], ...// with this a=1, b=2 and c=3
第三个参数kwargs为命名参数,按照名称传递给Python的方法参数。例如:
model.call("my_method",[], {a: 1, b: 2, c: 3}, ...// with this a=1, b=2 and c=3
OpenERP模型中的context是一个特殊参数,表示调用者的上下文,一般就使用客户端WebClient实例提供的instance.web.CompoundContext()类新建一个对象实例即可。CompoundContext类提供用户的语言和时区信息。也可以在构造函数中添加另外的数据:
model.call("my_method",[], {context: new instance.web.CompoundContext({'new_key': 'key_value'})})defdisplay_context(self, cr, uid, context=None): print context // will print:{'lang': 'en_US', 'new_key': 'key_value', 'tz': 'Europe/Brussels', 'uid': 1}
query()方法应用
本例中使用的mode的query方法
var model = new instance.web.Model("message_of_the_day");
model.query(["message","create_date"]).
filter([[id,'=',1], ['company_id', '=', main_company]])
.limit(15).all().then(function(result) {
self.$el.append($(QWeb.render("messageList", {msgList:result})));
});
model: 数据模型的query()方法的参数是需要读取的模型字段名称列表;该方法返回的是一个instance.web.Query()类型的查询对象实例,包括一些进一步定义查询结果的方法,这些方法返回的是同一个查询对象自身,因此可以链接:
filter():指定OpenERP 域(domain),也即过滤查询结果;limit():限制返回的记录数量。最后调用查询对象的all()方法执行查询。查询异步执行,all()返回的是一个deferred,因此要用then()提供回调函数来处理结果。数据模型的查询是通过rpc调用实现的。
self.$el得到模板中定义的message的根节点(div),append()方法将处理完成的页面内容赋值到根节点下。
$(QWeb.render("messageList",{msgList: result}))则是把result数组传递到模板为messageList中的msgList对象(此处是传递到该对象并进行遍历),返回完整的页面内容html代码。
Odoo中Qweb使用入门的更多相关文章
- Odoo中的模型继承、视图继承、Qweb模板继承详解
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826114.html 在实际开发过程中,经常会遇到需要修改Odoo原生逻辑的情况.然而,直接修改Odoo底 ...
- (19)odoo中的javascript
-----------更新日期15:17 2016-02-16 星期二-----------* 用到的js库 我们可以打开 addons/web/views/webclient_template. ...
- Odoo中的五种Action详解
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826232.html Odoo中的五种action都是继承自ir.actions.actions模型实现的 ...
- odoo13之在odoo中添加自定义页面
注: 本博文是阅读Ruter博客 在odoo中添加自定义页面 后所做的个人总结,以及博文搬迁,主要是便于自己的后期理解:大部分内容为搬运,当然也包括自己的一些总结和流程优化. 前言 首先展示效果:进入 ...
- MVC中使用SignaIR入门教程
一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...
- 利用Python的三元表达式解决Odoo中工资条中城镇、农村保险的问题
Python中没有像C#中有三元表达式 A?B:C 但在python中可以通过 A if condition else B 的方式来达到同样的效果. 例如 : 1 if True else 0 输出 ...
- Spring中IoC的入门实例
Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如 ...
- [置顶]
MVC中使用signalR入门教程
一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...
- Odoo 中使用 celery 实现高性能异步任务队列
详见:http://www.oejia.net/blog/2018/07/09/odoo_task_queue.html 概述 在 odoo 中可以用自带的cron实现异步任务,这个cron基于多线程 ...
随机推荐
- OrCAD(2) -- 编辑原理图库时的复制与粘贴
大家都知道,OrCAD元器件的管脚编辑是基于Excel的,但是在编辑原理图库的管脚的时候,大家应该都有体会'ctrl+c' 和 'ctrl+v' 的命令是不能用的. 这是因为该两个命令在OrCAD中都 ...
- Altera FPGA– Bit Slip
通过在接收端加延时,在延时间隙插入'0'或'1',以使最终接收和期望数据一致. BitSlip操作要注意几点: 1,BitSlip操作在rx_bitslip的上升沿即开始: 2,BitSlip操作开始 ...
- 校园商铺-2项目设计和框架搭建-8升级mysql驱动相关的配置以支持mysql8
1.如何升级驱动 1.1步骤: a 确保当前程序能正常访问数据库 b 更新mysql驱动重新运行程序进行校验 maven依赖https://mvnrepository.com/artifact/mys ...
- Spring整合Dubbo框架
Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用.演示过程创建两个小工程,一个作为服务的提供者,一个作为服务的消费者.通过Dubbo来实现服务消费者远程调用服务提供者的方法. d ...
- 026_JDBC
JDBC简介 JDBC(Java DataBase Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编 ...
- POJ 2074 /// 判断直线与线段相交 视野盲区
题目大意: 将所有物体抽象成一段横向的线段 给定房子的位置和人行道的位置 接下来给定n个障碍物的位置 位置信息为(x1,x2,y) 即x1-x2的线段 y相同因为是横向的 求最长的能看到整个房子的一段 ...
- 连接RDS数据库
- idea-----Intellij IDEA配置tomcat(非maven项目)
Intellij IDEA配置tomcat(非maven项目) 引用: https://blog.csdn.net/springlovejava/article/details/78570241 ID ...
- 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture
使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...
- Tensorflow入门篇
参考Tensorflow中文网(http://www.tensorfly.cn/tfdoc/get_started/introduction.html) ,写一个入门. 1.打开pyCharm,新建 ...