zoukankan      html  css  js  c++  java
  • Odoo 网页开发

    路径在网络中可访问

    request.make_response()     #   仅返回包含 HTML 的字符串
    
    request.render()   #  返回一个模板 
    
    # 对于 json请求 。 只需要返回客户端想要的数据结构即可。 
    # odoo 会处理序列化。让其动作,限制数据为json可序列化的类型
    
    # request.env 属性,包含了与模型self.env 相同的Environment对象。 
    # request.session    是werkzeug对Session对象的轻微封装。 OpenERPSession 对象
    
    # route 装饰器 可带有其他的参数来进一步定义其行为。 默认允许HTTP所有方法
    	 methods 参数 接收 方法列表
    # 允许跨域  设置cors参数
    
    # odoo 对每个请求传递 token 来保护请求免受跨站伪造请求 csrf的攻击
    
    # 多数据库  参考下面文字
    https://github.com/OCA/server-tools
    

    限制网络可访问路径的访问

    # auth='none'  任何用户都可以
    # auth='public'   公共用户
    # auth='user'      已验证的用户提供内容 ,通过request.env.user 指向有才能在用户
    
    
    # 验证方法  在base插件的ir.http模型中
    
    from odoo import exceptions, http, models
    from odoo.http import request
    
    
    class IrHttp(models.Model):
        _inherit = 'ir.http'
    
        def _auth_method_base_group_user(self):
            self._auth_method_user()
            if not request.env.user.has_group('base.group_user'):
                raise exceptions.AccessDenied()
    

    传递消耗参数到你的handler

    @http.route('/my_library/book_details', type='http', auth='none')
    def book_details(self, book_id):  # 传递参数 book_id
        record = request.env['library.book'].sudo().browse(int(book_id))
        return u'<html><body><h1>%s</h1>Authors: %s' % (
            record.name,
            u', '.join(record.author_ids.mapped('name')) or 'none',
        )
    
    操作response.headers来添加或删除HTTP头部
    渲染整个不同的模板,可以覆盖response.template
    response首先是否是基于QWeb,使用response.is_qweb进行查询
    response.render()可获取结果HTML代码
    

    管理静态资源

    web.assets_common   包含所有通用的基本工具:JQ ,Fa等资源。 odoo所有地方都加载
    
    web.assets_backend 包含所有与web客户端,视图,字段,组件,动作管理器相关代码
    
    web.assets_frontent  用于前台,所有与网站端相关的代码。 电商,博客,线上活动,论坛和在线聊天等。 不包含网站编辑和网站构造器
    
    web_editor.assets_editor和web_editor.summernote: 包含网站编辑组件以及拖拽功能。 批量邮件设计器
    
    web.report_assets_commo : QWeb 仅通过html 生成PDF文件
    
    
    
    ### odoo 通过  AssetsBundle 管理其静态资源
    		位于: /odoo/addons/base/models/assetsbundle.py
    		1. 多个 JavaScript 和css文件
    		2. 通过从文件内容中删除注释,多余空格以及回车换行来 最小化 JavaScript和Css文件、删除这些额外资源会减小静态资源的大小并提升页面速度
    		3. 对css 预处理的内置支持,如SASS和LESS。 自动会编译并添加到资源包中
    		4. 在达到4095的规则上限时它自动拆分样式表资源
    		
    		
    ### 页面引入
    	1. link 标签添加
    	2. QWeb中 使用 t-call-assets  引入   <t t-call-assets="my_module.my_custom_assets" tcss="false"/>
    
         3.t-css和 t-js属性公用于加载样式表或脚本
            
    # 开发阶段来说:  odoo资源仅会生成一次
    	命令中使用 dev=xml   这样会直接加载资源,无需重启服务
        
    

    拓展css和js

    # 1. 在已有页面 加载 样式和js
    	<link href="/my_library/static/src/css/my_library.css" rel="stylesheet" type="text/css"/>
    	<link href="/my_library/static/src/scss/my_library.scss" rel="stylesheet" type="text/scss"/>
    	<script src="/my_library/static/src/js/my_library.js" type="text/JavaScript" />
    # 2.  编写内容
    	参考地址:
    		https://alanhou.org/cms-website-development/
    		
    		
    			
    ### odoo  cms的底层名为QWeb的XML模板引擎。 
    		1. 通过 web.assets_frontend 中列出了样式表和JavaScript文件
    		2. scss 语法  : odoo12版本之前使用的是less预处理器,12版本后使用的bs4和SCSS预处理器
    		3.RequireJS 语法:
    				odoo.define('模块名',function(require){  //require 必要参数 
    					
    					 //代码
    					
    				})
    				
    

    创建或更改QWeb

    # contenteditable 属性 不可编辑 
    
    # t-call 调用模板  <t t-call="website.layout">
    # website.layout 包含所有需要的工具:如 bootstrap JQ fontAw 资源
    	# website.layout 包含默认的头部,底部 ,代码片段和页面编辑功能
        
    # t-foreach 属性,重复迭代成员
    	语法:    t-as  相当于 每个成员的别名,  t-esc输出别名
        		<t  t-foreach='[1,2,3]' t-as='num'>
        			<p><t t-esc='num'></p>
                </t>
                
                
     ## 查看 t-call 元素的内部。  末班通过上下文渲染
    	book_index  返回遍历中的当前索引值 ,从0开始
        book_first  和 book_last  分别在遍历第一个和最后一个时为True
        book_value 遍历的是一个字典会包含各项值。通过字典的键进行遍历
        book_size 集合的大小
        book_even   和  book_add  根据遍历的索引获取true的值
        book_parity 在遍历的索引为偶数时包含even的值,奇数时包含odd值
        
        
    # QWeb 动态设置属性值
    		1。t-att-$attr_name   创建一个$attr_name属性,它的值是任意有效的python表达式
        				<div  t-att-total="10+5+5"></div>
            						↓
                		<div total='20'></div>
                    
            2。 t-attf-$attr_name   与上一个区别是{{...}}和#{...} 之间的字符串
            		<t t-foreach="['info', 'danger', 'warning']" t-as="color">
                          <div t-attf-class="alert alert-#{color}">   
                            		Simple bootstrap alert
                          </div>
    				</t>
                    
               3。 t-att=mapping  选项,末班渲染自定后转换为属性和值接受这个字典
            		<div t-att= "{'id':'my_el_id', 'class': 'alert alert-danger'}"/>
            						↓
                    <div id='my_el_id'  class='alert alert-danger'/>
                    
                    
     # 字段  t-field 和 t-esc
    	t-field='字段名'
        t-options='{}'  # 传递一个字典,给字段设置渲染器   {'widget':'image'}
        t-esc  是 t-field的替代属性。 t-esc属性并不只局限与记录集,它也可以是任意数据类型。但在网站内不可编辑
        
        # t-field 和 t-esc 区别
        	t-field  基于用户的语言值
            t-esc 显示数据库中的原始值
            
    # 条件语句 t-if 
    	t-if="state == 'new'"
        t-elif="state == 'progress'"
        t-else=""
        
    #  设置变量
    	<t t-set='my_var' t-value='5+1'/>
        <t-esc='my_var'/>
        
    # 子模板
        <template id="first_template">
                <div> Test Template </div>
        </template>
    
        <template id="second_template">
                <t t-call="first_template"/>
        </template>
        
    # 行内编辑
    	  t-field 节点加载的数据 默认是可编辑的
    	  禁用行内编辑   contenteditable=False
    
     # 启用 页面拖拽 功能  oe_structure
    	 添加样式将开启 页面启用组件 拖拽功能  oe_structure
        
            
    # 网站编辑器编辑视图会在视图中设置noupdate标记。这表示后续的代码修改不会在客户的数据库中体现。
    # 继承  inherit_id 字段     
    
    

    动态路由

    @http.route('/books/<model("library.book"):book>', type='http', auth="user", website=True)
    def function(self,book):  # book 必须传递,否则报错
        pass
    
    
    # 视图   t-attf-href=设置动态属性, #{}  取值
     <a t-attf-href="/books/#{book.id}" class="btn btnprimary btn-sm">
          <i class="fa fa-book"/> Book Detail
    </a>
    
    
    
    
    #  其他动态路由
    	/page/接收一个整数
        /page/<any(about, help):page_name=””>接收给定的值
        /pages/<page>接收字符串
        /pages/<category>/<int:page>接收多个值
    
    

    为用户提供小组件

    https://alanhou.org/cms-website-development/
    
    # 1. 添加插件视图
    # 2. 添加 template 模板
    # 3. 继承 组件 website.snippets 。 添加组件和选项
    # 4. 在已继承的组件模板中添加组件选项
    # 5. 添加 css 和js脚本来调试
    
    

    从网站用户获取输入

    # 1. 需要一个模型来保存用户提交的问题
    	class LibraryBookIssues(models.Model):
                  _name = 'book.issue'
    
                  book_id = fields.Many2one('library.book', required=True)
                  submitted_by = fields.Many2one('res.users')
                  isuue_description = fields.Text()
                    
                    
    #2.   视图中添加 book_issuse_id 字段
    <group string="Book Issues">
            <field name="book_issue_id" nolabel="1">
                    <tree>
                            <field name="create_date"/>
                            <field name="submitted_by"/>
                            <field name="isuue_description"/>
                    </tree>
            </field>
    </group>
    
    
    # 3.  添加模型访问权限 ir.model.access.csv
    acl_book_issues,library.book_issue,model_book_issue,group_librarian,1,1,1,1
    
    
    # 4.  编写处理函数  在 main,py 新增一个路由函数
    @http.route('/books/submit_issues', type='http', auth="user", website=True)
    def books_issues(self, **post):
        pass   # 
    
    # 5.  添加一个 带有HTML表单的模板
    	<template>
        	....
        </template>
    # 6. 添加form 表单 , 解决csrf 问题
    	<form method='post'>
        	 <input type="hidden" name="csrf_token"    t-att-value="request.csrf_token()"/>
        </form>
    

    管理搜索引擎 优化SEO选项

    # odoo 模板提供了内置的SEO支持 。 希望为每个URL分离SEO选项
    
    
    # 继承 website.seo.metadata  mixin类
        _inherit = ['website.seo.metadata']
    
       
    odoo12 添加 对 openGrapht 和Twitter分享meta标签的支持。 如果希望在自己的页面添加自定义meta标签
    继承mixin后 重载 _default_website_meta() 
    
    
    

    管理网站的站点地图

    # 编写地图函数
    from odoo.addons.http_routing.models.ir_http import slug
    from odoo.addons.website.models.ir_http import sitemap_qs2dom
    
    class Main(http.Controller):
         ...
      	def sitemap_books(env, rule, qs):
                Books = env['library.book']
                dom = sitemap_qs2dom(qs, '/books', Books._rec_name)
                for f in Books.search(dom):
                  loc = '/books/%s' % slug(f)
                  if not qs or qs.lower() in loc:
                    yield {'loc': loc}
    
                    
     # 编写路由函数
    @http.route('/books/<model("library.book"):book>',type='http', auth="user", website=True, sitemap=sitemap_books ) # 添加地图
    def library_book_detail(self, book):
            pass
    

    获取访客的国家信息

    #  下载配置GeoIP内置支持
    
    # 添加字段保存国家
      restrict_country_ids = fields.Many2many('res.country')
    
    # 展示字段
    	  <field name="restrict_country_ids"  widget="many2many_tags"/>
        
     # 正确配置nginx  和GeoIP , odoo将会对request.session.geoip添加GeoIP信息
    country_code = request.session.geoip and request.session.geoip.get(‘country_code’) or ‘IN’
    

    追踪营销活动

    # ROI 投资回报率
    # UTM 广告的花费进行追踪
    
    # 1. depends  添加 utm模块 
            'depends': ['base', 'website', 'utm'],
     # 2. 继承 utm.mixin
    		  _inherit = ['utm.mixin']
    # 3.  compaign_id  添加到 视图表单中
    	      <field name="campaign_id"/>
    
        
    # # 继承了 utm.mixin  
    		campaign_id   :  tm.campaign模型的Many2one字段。它用于追踪不同的活动,如夏季和圣诞特价
            source_id:utm.source model.的Many2one字段。它用于追踪不同的来源,如搜索引擎和其它域名。
            medium_id:utm.medium 模型的Many2one字段。它用于追踪不同的媒介,如贺卡、邮件或横幅广告。
            
    

    管理多站点

    #  继承  website.multi.mixin
    _inherit = ['website.seo.metadata', 'website.multi.mixin']
    
    
    # 1. 控制访问 
            domain += request.website.website_domain()  # 将返回域名并过滤出不是来自该网站的图书。
    
    # 2.  can_access_from_current_website()    图书记录针对当前活跃网站的话方法can_access_from_current_website会返回值True,而针对另一个网站时返回False
        if not book.can_access_from_current_website():
            raise werkzeug.exceptions.NotFound()
    

    网页客户端开发

    自定义组件

    // # events  捕获js事件
                events: {
                  'click .o_color_pill': 'clickPill',
                },
    // # init 初始化  组件构造函数。用于进行初始化。在初始化组件时,会先调用该方法
            init: function () {
                          this.totalColors = 10;
                          this._super.apply(this, arguments);
            },
                
     // willStart():
                这个方法组件初始化以及在DOM中添加的过程中调用。它用于异步将数据初始化到组件中。它还会返回一个延迟对象,只需要通过super()调用即可获取。我们在后面的小节中将会使用到它
                
     // start()  
                该方法在完成组件渲染且未添加到DOM中时调用。这非常有助于后渲染任务,将返回一个延迟对象。可以在this.$el中访问已渲染的对象
                    
    // destroy()  
                消灭组件时调用  , 如 取消事件绑定
                
    // # 重载_renderEdit和_renderReadonly来设置DOM元素:
    
    
    // # 定义 点击 handler 
    
        clickPill: function (ev) {
                var $target = $(ev.currentTarget);
                var data = $target.data();
                if (mobile.methods.showToast) {
                    mobile.methods.showToast({ 'message': 'Color changed' });
                }
                this._setValue(data.val.toString());
        }
                    
                    
    // 注册组件 
                    fieldRegistry.add('int_color', colorField);
     //  插入组件
                      return {
                              colorField: colorField,
                              };  }); // closing 'my_field_widget' namespace
    

    客户端QWeb模板

    # QWeb的原因是其可扩展性, 客户端与服务端QWeb的很大区别在于。客户端无法使用Xpath表达式,需要使用jQuery选择器和操作
    
    <t t-extend=“FieldColorPills”>
          <t t-jquery=“span” t-operation=“prepend”>
            		<i class=“fa fa-user” />
          </t>
    </t>
    
    # t-name 属性 对应 字段
    # t-operation 属性  值: append  ,before ,after ,inner  , replace 。 attributes属性
    

    服务端做RPC调用

    
    
    # this.model 存储了当前模型的名称
    # this.field 是模型调用 fields_get函数的结果
    
    # 对于x2x字段,fields_get()函数会给出co-model或域的信息。也可以使用它来查询字段的string、size或其可在模型定义时为字段所设置的属性
    

    新建一个视图

    # 1. 新建视图  ir.ui.view 添加新视图模型
    	
    	################    抑郁 ~~~~~~~~~~~~~~~~~
    

    导览提升客户引导

    // 新增一个js
     
    
    odoo.define('my_library.tour', function (require) {
            "use strict";
            var core = require('web.core');
            var tour = require('web_tour.tour');  // 导入了 网站向导
            var _t = core._t;
            tour.register('library_tour', {   //注册向导
                url: "/web",   // 注册运行时需要的URL
            }, [
                tour.STEPS.SHOW_APPS_MENU_ITEM, {
                trigger: '.o_app[data-menuxmlid="my_library.library_base_menu"]',
                content: _t('Manage books and authors in<b>Library app</b>.'),
                position: 'right'    // 指定上下左右的位置
                },
                {
                trigger: '.o_list_button_add',
                content: _t("Let's create new book."),
                position: 'bottom'
            }, {
                trigger: 'input[name="name"]',
                extra_trigger: '.o_form_editable',
                content: _t('Set the book title'),
                position: 'right',
            }, {
                trigger: '.o_form_button_save',
                content: _t('Save this book record'),
                position: 'bottom',
            }
            ]);
    });
    
  • 相关阅读:
    Sandcastle 这个工具生成文档不错
    Windows 服务关闭自动重启
    『录』最全前端资源汇集
    利用Continuous Testing实现Eclipse环境自动单元测试
    (转载)const指针和指向const的指针(左值右指)
    为什么寄存器比内存快?
    Vim Buffer
    Linux操作系统文件系统基础知识详解(引用内容)
    详解BOM头以及去掉BOM头的方法
    对比MySQL,什么场景MongoDB更适用
  • 原文地址:https://www.cnblogs.com/dengz/p/14582185.html
Copyright © 2011-2022 走看看