OpenERP Web开发[通俗易懂]

OpenERP Web开发[通俗易懂]声明:本文非原创,原始出处为http://blog.csdn.net/mackz/article/details/22581517分类:原始页面:Welcome to OpenERP Web Training  在7和8下测试均可。  1.相关库/框架  主要:jQuery(使用1.8.3,如果使用新版本,其他jQuery插件也要升级或修改)、Underscore、QW

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

声明:本文非原创,原始出处为http://blog.csdn.net/mackz/article/details/22581517
分类:原始页面:Welcome to OpenERP Web Training
  在7和8下测试均可。

  
1.相关库/框架

  主要:jQuery(使用1.8.3,如果使用新版本,其他jQuery插件也要升级或修改)、Underscore、
QWeb

  其他:都在addons\web\static\lib路径下。

  
2.示例框架

  下载(需要先安装bzr):bzr branch lp:~niv-openerp/+junk/oepetstore -r 1

  下载后将路径加到OpenERP服务器的addons_path参数中,重启服务器、更新模块列表再安装。

  在__openerp__.py中通过:

[python] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. ‘js’: [‘static/src/js/*.js’],  
  2. ‘css’: [‘static/src/css/*.css’],  
  3. ‘qweb’: [‘static/src/xml/*.xml’],  

  将所有js/css/xml(QWeb模板)文件包含进来。

  oepetstore/static/js/petstore.js注释说明:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. openerp.oepetstore = function(instance) { // OpenERP模型,必须和模块名称相同。instance参数是OpenERP Web Client自动加载模块时传入的实例。  
  2.     var _t = instance.web._t,  
  3.         _lt = instance.web._lt; // 翻译函数  
  4.     var QWeb = instance.web.qweb; // QWeb实例  
  5.   
  6.     instance.oepetstore = {}; // instance实例里面的模块命名空间(namespace),比如和模块名称相同。  
  7.   
  8.     instance.oepetstore.HomePage = instance.web.Widget.extend({ // 自定义首页部件  
  9.         start: function() { // 部件创建时自动调用的方法  
  10.             console.log(“pet store home page loaded”);  
  11.         },  
  12.     });  
  13.   
  14.     instance.web.client_actions.add(‘petstore.homepage’‘instance.oepetstore.HomePage’);  
  15.     // 将自定义首页部件与菜单动作绑定  
  16. }  

  可以在网址后面加“?debug”参数使脚本不压缩以便于调试,例如:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. http://localhost:8069/?debug  

  
3.类的定义

  从instance.web.Class基类扩展:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.MyClass = instance.web.Class.extend({  
  2.     say_hello: function() {  
  3.         console.log(“hello”);  
  4.     },  
  5. });  
  6. var my_object = new instance.oepetstore.MyClass();  
  7. my_object.say_hello();  

  构造函数名为init();使用this访问对象实例的属性或方法:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.MyClass = instance.web.Class.extend({  
  2.     init: function(name) {  
  3.         this.name = name;  
  4.     },  
  5.     say_hello: function() {  
  6.         console.log(“hello”this.name);  
  7.     },  
  8. });  
  9.   
  10. var my_object = new instance.oepetstore.MyClass(“Nicolas”);  
  11. my_object.say_hello();  

  类可以通过extend()方法继承;使用this._super()调用基类被覆盖的方法。

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.MySpanishClass = instance.oepetstore.MyClass.extend({  
  2.     say_hello: function() {  
  3.         this._super();  
  4.         console.log(“translation in Spanish: hola”this.name);  
  5.     },  
  6. });  
  7.   
  8. var my_object = new instance.oepetstore.MySpanishClass(“Nicolas”);  
  9. my_object.say_hello();  

  
4.部件(Widget)

  从instance.web.Widget扩展自定义部件。HomePage首页部件见petstore.js。

  在自定义部件中,this.$el表示部件实例的jQuery对象,可以调用jQuery方法,例如:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.$el.append(“<div>Hello dear OpenERP user!</div>”);  

  往部件中添加一个<div>块及内容。

  部件中可以插入其他部件进行组合:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({  
  2.     start: function() {  
  3.         this.$el.addClass(“oe_petstore_greetings”);  
  4.         this.$el.append(“<div>We are so happy to see you again in this menu!</div>”);  
  5.     },  
  6. });  
  7. instance.oepetstore.HomePage = instance.web.Widget.extend({  
  8.     start: function() {  
  9.         this.$el.addClass(“oe_petstore_homepage”);  
  10.         this.$el.append(“<div>Hello dear OpenERP user!</div>”);  
  11.         var greeting = new instance.oepetstore.GreetingsWidget(this); // 创建部件的时候传入父部件的实例作为构造参数。  
  12.         greeting.appendTo(this.$el);  
  13.     },  
  14. });  

  父子部件可以通过getChildren()、getParent()进行互相访问。如果重载部件的构造函数,第一个参数必须是父部件,并且必须传递给基类。

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({  
  2.     init: function(parent, name) {  
  3.         this._super(parent);  
  4.         this.name = name;  
  5.     },  
  6. });  

  如果作为顶层部件创建,parent参数应该是null。

  部件实例可以调用destroy()方法销毁。

  
5.QWeb模板引擎

  QWeb模板在XML属性上加前缀“t-”表示:

    t-name:模板名称;

    t-esc:引用实例参数,可以使用任意JavaScript表达式;

    t-raw:引用原始实例参数,如果有html标记则保留。

  QWeb模板下面的根元素最好只有一个。

  oepetstore/static/src/xml/petstore.xml:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2.   
  3. <templates xml:space=“preserve”>  
  4.     <t-name=“HomePageTemplate”>  
  5.         <div style=“background-color: red;”>  
  6.             <div>Hello <t-esc=“name”/></div>  
  7.             <div><t-esc=“3+5”/></div>  
  8.             <div><t-raw=“some_html”/></div>  
  9.         </div>  
  10.     </t>  
  11. </templates>  

  定义一个名为“HomePageTemplate”的模板。

  使用方法1:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.HomePage = instance.web.Widget.extend({  
  2.     start: function() {  
  3.         this.$el.append(QWeb.render(“HomePageTemplate”));  
  4.     },  
  5. });  

  使用方法2:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.HomePage = instance.web.Widget.extend({  
  2.     template: “HomePageTemplate”,  
  3.     start: function() {  
  4.         …  
  5.     },  
  6. });  

  模板里面的条件控制t-if:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <t-if=“true == true”>  
  2.     true is true  
  3. </t>  
  4. <t-if=“true == false”>  
  5.     true is not true  
  6. </t>  

  枚举t-foreach和t-as:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <t-foreach=“names” t-as=“name”>  
  2.     <div>  
  3.         Hello <t-esc=“name”/>  
  4.     </div>  
  5. </t>  

  属性赋值,在属性名前加前缀“t-att-”:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <input type=“text” t-att-value=“defaultName”/>  

  将input控件的value属性赋值为“defaultName”。

  部件开发示例,显示产品列表。

  JavaScript脚本:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. openerp.oepetstore = function(instance) {  
  2.     var _t = instance.web._t,  
  3.         _lt = instance.web._lt;  
  4.     var QWeb = instance.web.qweb;  
  5.   
  6.     instance.oepetstore = {};  
  7.   
  8.     instance.oepetstore.HomePage = instance.web.Widget.extend({  
  9.         start: function() {  
  10.             var products = new instance.oepetstore.ProductsWidget(this, [“cpu”“mouse”“keyboard”“graphic card”“screen”], “#00FF00”);  
  11.             products.appendTo(this.$el);  
  12.         },  
  13.     });  
  14.   
  15.     instance.oepetstore.ProductsWidget = instance.web.Widget.extend({  
  16.         template: “ProductsWidget”,  
  17.         init: function(parent, products, color) {  
  18.             this._super(parent);  
  19.             this.products = products;  
  20.             this.color = color;  
  21.         },  
  22.     });  
  23.   
  24.     instance.web.client_actions.add(‘petstore.homepage’‘instance.oepetstore.HomePage’);  
  25. }  

  QWeb模板:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2.   
  3. <templates xml:space=“preserve”>  
  4.     <t-name=“ProductsWidget”>  
  5.         <div>  
  6.             <t-foreach=“widget.products” t-as=“product”>  
  7.                 <span class=“oe_products_item” t-att-style=“‘background-color: ‘ + widget.color + ‘;'”><t-esc=“product”/></span><br/>  
  8.             </t>  
  9.         </div>  
  10.     </t>  
  11. </templates>  

  CSS样式:

[css] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. .oe_products_item {  
  2.     display: inline-block;  
  3.     padding3px;  
  4.     margin5px;  
  5.     border1px solid black;  
  6.     border-radius: 3px;  
  7. }  

  
6.部件事件与特性

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.ConfirmWidget = instance.web.Widget.extend({  
  2.     start: function() {  
  3.         var self = this;  
  4.         this.$el.append(“<div>Are you sure you want to perform this action?</div>” +  
  5.             “<button class=’ok_button’>Ok</button>” +  
  6.             “<button class=’cancel_button’>Cancel</button>”);  
  7.         this.$el.find(“button.ok_button”).click(function() { // 在按钮上绑定click事件  
  8.             self.trigger(“user_choose”true); // 触发自定义user_choose事件,传递事件参数true/false  
  9.         });  
  10.         this.$el.find(“button.cancel_button”).click(function() {  
  11.             self.trigger(“user_choose”false);  
  12.         });  
  13.     },  
  14. });  
  15.   
  16. instance.oepetstore.HomePage = instance.web.Widget.extend({  
  17.     start: function() {  
  18.         var widget = new instance.oepetstore.ConfirmWidget(this);  
  19.         widget.on(“user_choose”thisthis.user_choose); // 在部件上绑定user_choose事件到响应函数user_choose  
  20.         widget.appendTo(this.$el);  
  21.     },  
  22.     user_choose: function(confirm) {  
  23.         if (confirm) {  
  24.             console.log(“The user agreed to continue”);  
  25.         } else {  
  26.             console.log(“The user refused to continue”);  
  27.         }  
  28.     },  
  29. });  

  部件特性(Properties)的使用:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.widget.on(“change:name”thisthis.name_changed); //绑定name特性的change事件  
  2. this.widget.set(“name”“Nicolas”); // 设置特性值  
  3. var getedname = this.widget.get(“name”); // 读取特性值  

  
7.部件访问  简化jQuery选择器:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.$el.find(“input.my_input”)  

  等于

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.$(“input.my_input”)  

  因此事件的绑定:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.$el.find(“input”).change(function() {  
  2.                 self.input_changed();  
  3.             });  

  可以简化为:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. this.$(“.my_button”).click(function() {  
  2.             self.button_clicked();  
  3.         });  

  进一步,可以通过部件提供的events字典属性简化为:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.MyWidget = instance.web.Widget.extend({  
  2.     events: {  
  3.         “click .my_button”“button_clicked”,  
  4.     },  
  5.     button_clicked: function() {  
  6.         ..  
  7.     }  
  8. });  

  注意:这种方法只是绑定jQuery提供的DOM事件机制,不能用于部件的on语法绑定部件自身的事件。  event属性的键名由两部分组成:事件名称和jQuery选择器,用空格分开。属性值是响应事件的函数(方法)。

  事件使用示例:

  JavaScript脚本:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. openerp.oepetstore = function(instance) {  
  2.     var _t = instance.web._t,  
  3.         _lt = instance.web._lt;  
  4.     var QWeb = instance.web.qweb;  
  5.   
  6.     instance.oepetstore = {};  
  7.   
  8.     instance.oepetstore.ColorInputWidget = instance.web.Widget.extend({  
  9.         template: “ColorInputWidget”,  
  10.         start: function() {  
  11.             var self = this;  
  12.             this.$el.find(“input”).change(function() {  
  13.                 self.input_changed();  
  14.             });  
  15.             self.input_changed();  
  16.         },  
  17.         input_changed: function() {  
  18.             var color = “#”;  
  19.             color += this.$el.find(“.oe_color_red”).val();  
  20.             color += this.$el.find(“.oe_color_green”).val();  
  21.             color += this.$el.find(“.oe_color_blue”).val();  
  22.             this.set(“color”, color);  
  23.         },  
  24.     });  
  25.   
  26.     instance.oepetstore.HomePage = instance.web.Widget.extend({  
  27.         template: “HomePage”,  
  28.         start: function() {  
  29.             this.colorInput = new instance.oepetstore.ColorInputWidget(this);  
  30.             this.colorInput.on(“change:color”thisthis.color_changed);  
  31.             this.colorInput.appendTo(this.$el);  
  32.         },  
  33.         color_changed: function() {  
  34.             this.$el.find(“.oe_color_div”).css(“background-color”this.colorInput.get(“color”));  
  35.         },  
  36.     });  
  37.   
  38.     instance.web.client_actions.add(‘petstore.homepage’‘instance.oepetstore.HomePage’);  
  39. }  

  QWeb模板:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2.   
  3. <templates xml:space=“preserve”>  
  4.     <t-name=“ColorInputWidget”>  
  5.         <div>  
  6.             Red: <input type=“text” class=“oe_color_red” value=“00”></input><br />  
  7.             Green: <input type=“text” class=“oe_color_green” value=“00”></input><br />  
  8.             Blue: <input type=“text” class=“oe_color_blue” value=“00”></input><br />  
  9.         </div>  
  10.     </t>  
  11.     <t-name=“HomePage”>  
  12.         <div>  
  13.             <div class=“oe_color_div”></div>  
  14.         </div>  
  15.     </t>  
  16. </templates>  

  CSS样式:

[css] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. .oe_color_div {  
  2.     width100px;  
  3.     height100px;  
  4.     margin10px;  
  5. }  

  
8.修改已有的部件和类

  可以用include()方法重载已有的部件和类,这个和继承机制类似,是一种插入的方法:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. var TestClass = instance.web.Class.extend({  
  2.     testMethod: function() {  
  3.         return “hello”;  
  4.     },  
  5. });  
  6.   
  7. TestClass.include({  
  8.     testMethod: function() {  
  9.         return this._super() + ” world”;  
  10.     },  
  11. });  
  12.   
  13. console.log(new TestClass().testMethod());  
  14. // will print “hello world”  

  应尽量避免使用这种机制导致的复杂性。

  
9.与服务器的交互-读取数据模型

  客户端使用Ajax与服务器交互,不过OpenERP框架提供了简化的方法,通过数据模型进行访问。

  OpenERP自动将服务端的数据模型转化为客户端端模型,直接调用即可。服务器上petstore.py里面的模型:

[python] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. class message_of_the_day(osv.osv):  
  2.     _name = “message_of_the_day”  
  3.   
  4.     def my_method(self, cr, uid, context=None):  
  5.         return {
    “hello”“world”}  
  6.   
  7.     _columns = {  
  8.         ‘message’: fields.text(string=“Message”),  
  9.         ‘color’: fields.char(string=“Color”, size=20),  
  10.     }  

  客户端调用例子:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. instance.oepetstore.HomePage = instance.web.Widget.extend({  
  2.     start: function() {  
  3.         var self = this;  
  4.         var model = new instance.web.Model(“message_of_the_day”);  
  5.         model.call(“my_method”, [], {context: new instance.web.CompoundContext()}).then(function(result) {  
  6.             self.$el.append(“<div>Hello “ + result[“hello”] + “</div>”);  
  7.             // will show “Hello world” to the user  
  8.         });  
  9.     },  
  10. });  

  模型的call()方法参数:

    第一个参数name是方法的名称;

    第二个参数args是按照顺序排列的参数数组。OpenERP定义的模型方法前三个参数(self, cr, uid)是固定的,由框架产生,也就是说传递的参数数组从第四个开始插入。而context又是特殊的。例子:

    方法定义:

[python] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. def my_method2(self, cr, uid, a, b, c, context=None):  

  调用:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. model.call(“my_method”, [1, 2, 3], …// with this a=1, b=2 and c=3  

    第三个参数kwargs为命名参数,按照名称传递给Python的方法参数。例如:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. model.call(“my_method”, [], {a: 1, b: 2, c: 3}, …// with this a=1, b=2 and c=3  

  OpenERP模型中的context是一个特殊参数,表示调用者的上下文,一般就使用客户端Web Client实例提供的instance.web.CompoundContext()类新建一个对象实例即可。

  CompoundContext类提供用户的语言和时区信息。也可以在构造函数中添加另外的数据:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. model.call(“my_method”, [], {context: new instance.web.CompoundContext({
    ‘new_key’‘key_value’})})def display_context(self, cr, uid, context=None):    print context    // will print: {‘lang’: ‘en_US’, ‘new_key’: ‘key_value’, ‘tz’: ‘Europe/Brussels’, ‘uid’: 1}  

  (OpenERP服务器端数据模型的方法必须提供4个参数:self, cr, uid, context=None,分别表示模型实例、数据库指针(Cursor)、用户id和用户上下文)

  
10.与服务器的交互-查询

  客户端数据模型提供了search()、read()等方法,组合为query()方法,使用例子:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. model.query([‘name’‘login’‘user_email’‘signature’])     .filter([[‘active’‘=’true], [‘company_id’‘=’, main_company]])     .limit(15)     .all().then(function (users) {    // do work with users records});  

  数据模型的query()方法的参数是需要读取的模型字段名称列表;该方法返回的是一个instance.web.Query()类型的查询对象实例,包括一些进一步定义查询结果的方法,这些方法返回的是同一个查询对象自身,因此可以链接:

    filter():指定OpenERP 域(domain),也即过滤查询结果;

    limit():限制返回的记录数量。

  最后调用查询对象的all()方法执行查询。

  查询异步执行,all()返回的是一个deferred,因此要用then()提供回调函数来处理结果。

  数据模型的查询是通过rpc调用实现的。

  示例1:显示每日提示

  JavaScript脚本:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. openerp.oepetstore = function(instance) {  
  2.     var _t = instance.web._t,  
  3.         _lt = instance.web._lt;  
  4.     var QWeb = instance.web.qweb;  
  5.   
  6.     instance.oepetstore = {};  
  7.   
  8.     instance.oepetstore.HomePage = instance.web.Widget.extend({  
  9.         template: “HomePage”,  
  10.         start: function() {  
  11.             var motd = new instance.oepetstore.MessageOfTheDay(this);  
  12.             motd.appendTo(this.$el);  
  13.         },  
  14.     });  
  15.   
  16.     instance.web.client_actions.add(‘petstore.homepage’‘instance.oepetstore.HomePage’);  
  17.   
  18.     instance.oepetstore.MessageOfTheDay = instance.web.Widget.extend({  
  19.         template: “MessageofTheDay”,  
  20.         init: function() {  
  21.             this._super.apply(this, arguments);  
  22.         },  
  23.         start: function() {  
  24.             var self = this;  
  25.             new instance.web.Model(“message_of_the_day”).query([“message”]).first().then(function(result) {  
  26.                 self.$(“.oe_mywidget_message_of_the_day”).text(result.message);  
  27.             });  
  28.         },  
  29.     });  
  30.   
  31. }  

  QWeb模板:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2.   
  3. <templates xml:space=“preserve”>  
  4.     <t-name=“HomePage”>  
  5.         <div class=“oe_petstore_homepage”>  
  6.         </div>  
  7.     </t>  
  8.     <t-name=“MessageofTheDay”>  
  9.         <div class=“oe_petstore_motd”>  
  10.             <p class=“oe_mywidget_message_of_the_day”></p>  
  11.         </div>  
  12.     </t>  
  13. </templates>  

  CSS样式:

[css] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. .oe_petstore_motd {  
  2.     margin5px;  
  3.     padding5px;  
  4.     border-radius: 3px;  
  5.     background-color#F0EEEE;  
  6. }  

  示例2:组合显示每日提示和产品列表

  服务器端从OpenERP的产品表继承一个类(模型):

[python] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. class product(osv.osv):  
  2.        _inherit = “product.product”  
  3.     
  4.        _columns = {  
  5.            ‘max_quantity’: fields.float(string=“Max Quantity”),  
  6.        }  

  因此数据是保存在product.product表中的,只是扩充了一个“max_quantity”字段;这个例子结合前面的每日提示信息,显示二列,左面一列显示产品列表,右面显示提示信息。

  JavaScript脚本:

[javascript] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. openerp.oepetstore = function(instance) {  
  2.     var _t = instance.web._t,  
  3.         _lt = instance.web._lt;  
  4.     var QWeb = instance.web.qweb;  
  5.   
  6.     instance.oepetstore = {};  
  7.   
  8.     instance.oepetstore.HomePage = instance.web.Widget.extend({  
  9.         template: “HomePage”,  
  10.         start: function() {  
  11.             var pettoys = new instance.oepetstore.PetToysList(this);  
  12.             pettoys.appendTo(this.$(“.oe_petstore_homepage_left”));  
  13.             var motd = new instance.oepetstore.MessageOfTheDay(this);  
  14.             motd.appendTo(this.$(“.oe_petstore_homepage_right”));  
  15.         },  
  16.     });  
  17.   
  18.     instance.web.client_actions.add(‘petstore.homepage’‘instance.oepetstore.HomePage’);  
  19.   
  20.     instance.oepetstore.MessageOfTheDay = instance.web.Widget.extend({  
  21.         template: “MessageofTheDay”,  
  22.         init: function() {  
  23.             this._super.apply(this, arguments);  
  24.         },  
  25.         start: function() {  
  26.             var self = this;  
  27.             new instance.web.Model(“message_of_the_day”).query([“message”]).first().then(function(result) {  
  28.                 self.$(“.oe_mywidget_message_of_the_day”).text(result.message);  
  29.             });  
  30.         },  
  31.     });  
  32.   
  33.     instance.oepetstore.PetToysList = instance.web.Widget.extend({  
  34.         template: “PetToysList”,  
  35.         start: function() {  
  36.             var self = this;  
  37.             new instance.web.Model(“product.product”).query([“name”“image”])  
  38.                 .filter([[“categ_id.name”“=”“Pet Toys”]]).limit(5).all().then(function(result) {  
  39.                 _.each(result, function(item) {  
  40.                     var $item = $(QWeb.render(“PetToy”, {item: item}));  
  41.                     self.$el.append($item);  
  42.                 });  
  43.             });  
  44.         },  
  45.     });  
  46.   
  47. }  

  QWeb模板:

[html] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2.   
  3. <templates xml:space=“preserve”>  
  4.     <t-name=“HomePage”>  
  5.         <div class=“oe_petstore_homepage”>  
  6.             <div class=“oe_petstore_homepage_left”></div>  
  7.             <div class=“oe_petstore_homepage_right”></div>  
  8.         </div>  
  9.     </t>  
  10.     <t-name=“MessageofTheDay”>  
  11.         <div class=“oe_petstore_motd”>  
  12.             <p class=“oe_mywidget_message_of_the_day”></p>  
  13.         </div>  
  14.     </t>  
  15.     <t-name=“PetToysList”>  
  16.         <div class=“oe_petstore_pettoyslist”>  
  17.         </div>  
  18.     </t>  
  19.     <t-name=“PetToy”>  
  20.         <div class=“oe_petstore_pettoy”>  
  21.             <p><t-esc=“item.name”/></p>  
  22.             <p><img t-att-src=“‘data:image/jpg;base64,’+item.image”/></p>  
  23.         </div>  
  24.     </t>  
  25. </templates>  

  CSS样式:

[css] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. .oe_petstore_homepage {  
  2.     display: table;  
  3. }  
  4.   
  5. .oe_petstore_homepage_left {  
  6.     displaytable-cell;  
  7.     width : 300px;  
  8. }  
  9.   
  10. .oe_petstore_homepage_right {  
  11.     displaytable-cell;  
  12.     width : 300px;  
  13. }  
  14.   
  15. .oe_petstore_motd {  
  16.     margin5px;  
  17.     padding5px;  
  18.     border-radius: 3px;  
  19.     background-color#F0EEEE;  
  20. }  
  21.   
  22. .oe_petstore_pettoyslist {  
  23.     padding5px;  
  24. }  
  25.   
  26. .oe_petstore_pettoy {  
  27.     margin5px;  
  28.     padding5px;  
  29.     border-radius: 3px;  
  30.     background-color#F0EEEE;  
  31. }  
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234179.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Android ListView那些事

    Android ListView那些事ListView是我们在开发Android程序时用得比较多的一种widget,通常用来展示多条数据,这里,我对ListView的一些功能点作一个简单介绍。1. Cachecolorhint默认情况下,Android中的View的背景都是透明的,这是一个合理的设计,但是,当渲染到屏幕上时,这会引入许多的计算,因为所有的child的背景是透明的,这就意味着当ListView绘制它的chil

  • java中map转json[通俗易懂]

    java中map转json[通俗易懂]在日常的使用中,我们一般会遇到map转json,如果遍历的话会浪费大量的时间,其实我们拥有这样的jar包Themethod ***isundefinedforthetypeJSONObject缺哪个包——json-lib.jar这样还是不行的需要一个依赖的jar包要不然会报错java.lang.ClassNotFoundException:

  • 使用rpm安装telnet软件并实现远程登录

    使用rpm安装telnet软件并实现远程登录一、RPM包管理工具的使用1、RPM包管理工具介绍·RedHat软件包管理工具(RedHatPackageManager,RPM)·RPM软件包工具常用于软件包的安装、查询、更新升级、校验、卸载以及生成.rpm格式的软件包等操作。·RPM软件包工具只能管理后缀是.rpm的软件包。软件包的命名格式:·软件名称-版本号(包括主版本号和次版本号).软件运行的硬件平台.rpm例:telnet-server-0.17-59.el7.x86_64.rpm。2、RPM工具的使用RPM

  • 接口测试工具Postman接口测试图文教程

    接口测试工具Postman接口测试图文教程市场上有很多优秀的,完善的接口测试工具,比如SoapUI,Postman等,能够高效的帮助后端开发人员独立进行接口测试。这里使用Postman接口测试工具,此处以请求方式为POST的userLogin登录接口为例。

  • pycharm django环境搭建_java项目框架搭建流程

    pycharm django环境搭建_java项目框架搭建流程前提是,已经知道了运行Django最好使用派恰姆的专业版,由于本人不想再重新下载新的软件,于是找到了只用社区版就可以运行框架的办法,在这里记录一下。首先用虚拟的virtualenv新建项目安装djangopipinstalldjango输入命令行django-adminstartproject[foldername]如上图所示,django框架已新建好5.启动pythonmanage.pyrunserver成功!…

  • python爬虫,selenium+chromedriver,谷歌驱动自动下载及配置

    python爬虫,selenium+chromedriver,谷歌驱动自动下载及配置我们在使用selenium时,有一件让我们狠抓狂的事,那就是驱动的下载与配置…为什么这么说呢?

    2022年10月23日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号