odoo前后端交互详解

为了简单叙述,暂时不考虑多个db的情况(主要是懒得说没有db或者多个db实例的情况)当odoo指定数据库开启服务时(也就是odoo-bin -d <some_db_name> ),我们使用chrome的隐身模式访问http://127.0.0.1:8069

1. 输入http://127.0.0.1:8069/之后发生了什么

192.168.1.10, 这个是我的虚机ip地址,返回响应是200,可以通过源代码中, 我们看到

# web/controllers/main.py:435

@http.route(‘/‘, type=‘http‘, auth=‘none‘)
def index(self, s_action=None, db=None, **kwargs):
        return http.local_redirect(‘/web‘, query=request.params, keep_hash=True)

按照代码命名来看,应该返回一个30x的redirect[重定向]响应,为什么实际返回的确是200的响应头呢?
继续查看代码,可以发现就是keep_hash=True 这个参数所引起的,在local_redirect 函数中由于keep_hash,

# odoo/http.py:156
def redirect_with_hash(url, code=303):
    if request.httprequest.user_agent.browser in (‘firefox‘,):
        return werkzeug.utils.redirect(url, code)
    url = pycompat.to_text(url)
    if urls.url_parse(url, scheme=‘http‘).scheme not in (‘http‘, ‘https‘):
        url = u‘http://‘ + url
    url = url.replace("‘", "%27").replace("<", "%3C")
    return "<html><head><script>window.location = ‘%s‘ + location.hash;</script></head></html>" % url

调用了redirect_with_hash 函数,而多数浏览器是不支持带着hash redirect的,就直接返回了html,并且带有script的js代码,使得从js的角度实现带有hash地址的redirect。
通过curl命令验证,实际上确实是如此返回

2. 跳转至/web之后

# web/controllers/main.py:442
@http.route(‘/web‘, type=‘http‘, auth="none")
def web_client(self, s_action=None, **kw):
    ensure_db()
    if not request.session.uid:
        return werkzeug.utils.redirect(‘/web/login‘, 303)
    if kw.get(‘redirect‘):
        return werkzeug.utils.redirect(kw.get(‘redirect‘), 303)

    request.uid = request.session.uid
    try:
        context = request.env[‘ir.http‘].webclient_rendering_context()
        response = request.render(‘web.webclient_bootstrap‘, qcontext=context)
        response.headers[‘X-Frame-Options‘] = ‘DENY‘
        return response
    except AccessError:
        return werkzeug.utils.redirect(‘/web/login?error=access‘)

ensure_db(),就是一些确定当前用户是否选择db,没有就跳转到/web/database/selector, 或者/web/database/create,由于上面我说了只使用一个db,因为其他情况不想多讲,所以在ensure_db中,默认替我们选择好了唯一一个db,并且存在request.session中了。接下来,由于我们尚未登陆,request.session.uid为空,就返回了 /web/login 303的响应。

3. 跳转至/web/login

# web/controllers/main.py:467
@http.route(‘/web/login‘, type=‘http‘, auth="none", sitemap=False)
def web_login(self, redirect=None, **kw):
    ensure_db()
    request.params[‘login_success‘] = False

    # 如果是带有redirect的get请求,并且session中有uid(也就是用户已经登陆的情况下),返回redirect
    # 我们目前不是这个情况
    if request.httprequest.method == ‘GET‘ and redirect and request.session.uid:
        return http.redirect_with_hash(redirect)

    # 设置request.uid
    if not request.uid:
        request.uid = odoo.SUPERUSER_ID

    values = request.params.copy()
    try:
        values[‘databases‘] = http.db_list()
    except odoo.exceptions.AccessDenied:
        values[‘databases‘] = None

    # 登陆的相关逻辑
    if request.httprequest.method == ‘POST‘:
        old_uid = request.uid
        uid = request.session.authenticate(request.session.db, request.params[‘login‘], request.params[‘password‘])
        if uid is not False:
            request.params[‘login_success‘] = True
            return http.redirect_with_hash(self._login_redirect(uid, redirect=redirect))
        request.uid = old_uid
        values[‘error‘] = _("Wrong login/password")
    else:
        if ‘error‘ in request.params and request.params.get(‘error‘) == ‘access‘:
            values[‘error‘] = _(‘Only employee can access this database. Please contact the administrator.‘)

    if ‘login‘ not in values and request.session.get(‘auth_login‘):
        values[‘login‘] = request.session.get(‘auth_login‘)

    if not odoo.tools.config[‘list_db‘]:
        # 这个值决定了是否在登陆界面出现Manage Databases超链接
        values[‘disable_database_manager‘] = True

    # GET请求,返回的响应就是这个了,
    response = request.render(‘web.login‘, values)
    response.headers[‘X-Frame-Options‘] = ‘DENY‘
    return response

到这,就不得不提一下odoo自己的Qweb模板引擎了,这个‘web.login‘,就是qweb view的id,具体可以通过全局查找定位到‘web.login‘ 的位置,其实就是在web/views/webclient_templates.xml中301行的位置,qweb有它自己独特的语法,这个要了解就去odoo官网查看吧,然后通过values对这个模板进行渲染,然后返回200的响应,就出现了基本的登录界面了  

综上,这就是基本的输入界面到返回界面的一些过程。
例子 - 去除登陆页面的Powered by Odoo链接

从上面的第3步,我们可以看到,最后登录界面是由‘web.login‘ 模板来显示的,通过odoo的继承方式,我们很容易的就可以去除这个链接,通过查找,这个链接实际是出现在‘web.login_layout‘ qweb视图中,

<template id=‘remove_login_odoo_link‘ inherit_id=‘web.login_layout‘>
    <xpath expr=‘//div[@t-if="not disable_footer"]‘ position=‘replace‘>
        <div class="text-right" t-if="not disable_footer">
            <t t-if="not disable_database_manager">
                <a class="" href="/web/database/manager">Manage Databases</a>
            </t>
        </div>
    </xpath>
</template> 
<odoo>
    <data>
        <template id="assets_backend" inherit_id="web.assets_backend" name="title assets backend">
            <xpath expr="." position="inside">
                <script type="text/javascript" src="/remove_login_odoo_link/static/src/title.js"></script>
            </xpath>
        </template>

        <!--移除/web/login界面中, Powered by Odoo的超链接-->
        <template id=‘remove_login_odoo_link‘ inherit_id=‘web.login_layout‘>
            <xpath expr=‘//a[@href="https://www.odoo.com"]‘ position=‘replace‘/>
            <xpath expr="//t[@t-if=‘not disable_database_manager‘]" position="replace">
                <a class="" href="/web/database/manager">Manage Databases</a>
            </xpath>
        </template>

        <!--替换/web/login下的 title-->
        <template id=‘remove_web_head_title‘ inherit_id=‘web.layout‘>
            <xpath expr=‘//head/title‘ position=‘replace‘>
                <title t-esc="title"/>
            </xpath>
        </template>

    </data>
</odoo>

odoo面试题---笔试题

1.什么是lambda函数?

Python的匿名函数lambda函数lambda函数定义

python 使用 lambda 来创建匿名函数。lambda函数的语法只包含一个语句,如下:                 参数    表达式    lambda [arg1 [,arg2,.....argn]]:expression

简单理解起来。匿名函数lambda是指一类无需定义标识符(函数名)的函数或子程序。lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。

lambda匿名函数的格式:冒号前是参数,可以有多个,用逗号隔开,冒号右边的为表达式。其实lambda返回值是一个函数的地址,也就是函数对象。lambda函数实例

s=lambda x,y:x+yh=lambda x,y,z:x+y-zprint(s(10,20),h(10,20,50))

lambda函数的特点和使用场景特点

    从函数命名的角度:匿名,直接返回可供调用的值    从输入输出的角度:支持多个输入参数,但只支持一个表达式    从函数功能的角度:结构简单,无须定义函数名。但所能实现的功能也极其受限。    从访问变量的角度:只支持访问lambda自己定义的变量。不支持外部变量访问    从运行效率的角度:lambda实际上仍开辟了一个内存单元,并没有提升运行效率

使用场景

    lambda函数复制给变量:减少函数定义的麻烦,同时支持代码复用。

    add=lambda x,y:x+y    print(add(1,2))

    lambda函数赋值给函数:利用lambda函数实现对已有函数的重新定义。

    例如,为了把标准库time中的函数sleep的功能屏蔽(Mock),我们可以在程序初始化时调用:time.sleep=lambda x:None。这样,在后续代码中调用time库的sleep函数将不会执行原有的功能。例如,执行time.sleep(3)时,程序不会休眠3秒钟,而是什么都不做。

    利用lambda函数进行函数嵌套:利用lambda构造嵌套的内部和外部函数,实现闭包编程 

部分Python内置函数接收函数作为参数。典型的此类内置函数有这些。

- filter函数。此时lambda函数用于指定过滤列表元素的条件。例如filter(lambda x: x % 3 == 0, [1, 2, 3])指定将列表[1,2,3]中能够被3整除的元素过滤出来,其结果是[3]。- sorted函数。此时lambda函数用于指定对列表中所有元素进行排序的准则。例如sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]按照元素与5距离从小到大进行排序,其结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]。- map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如map(lambda x: x+1, [1, 2,3])将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。- reduce函数。此时lambda函数用于指定列表中两两相邻元素的结合条件。例如reduce(lambda a, b: ‘{}, {}‘.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])将列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]中的元素从左往右两两以逗号分隔的字符的形式依次结合起来,其结果是‘1, 2, 3, 4, 5, 6, 7, 8, 9‘。

原文链接:https://blog.csdn.net/zhanshen112/article/details/90603865

2.如何判断一个对象的类型

a = 10

利用python的type()函数,

print(type(a))   输出:int

3.字典和json数据的转换

字典与json转化主要用到以下方法:

   loads():将json数据转化成dict数据
   dumps():将dict数据转化成json数据

字典转json数据:In [5]: import json                                                                                                                                                                                                                                                           

In [6]: dict = {‘name‘:‘mary‘,‘age‘:21}                                                                                                                                                                                                                                       

In [7]: type(dict)                                                                                                                                                                                                                                                            Out[7]: dict

In [8]: j = json.dumps(dict)                                                                                                                                                                                                                                                  

In [9]: j                                                                                                                                                                                                                                                                     Out[9]: ‘{"name": "mary", "age": 21}‘

这里需要注意的是,如果字典转json时包含汉字,就会出现编码问题,如下:

In [29]: staff = {‘name‘:‘权权‘,‘age‘:23,‘sex‘:‘女‘}                                                                                                                                                                                                                          

In [30]: json.dumps(staff)                                                                                                                                                                                                                                                    Out[30]: ‘{"name": "\\u6743\\u6743", "age": 23, "sex": "\\u5973"}‘

    1    2    3    4    5

所以如果有中文,我们需要加参数处理:

In [31]: json.dumps(staff,ensure_ascii=False)                                                                                                                                                                                                                                 Out[31]: ‘{"name": "权权", "age": 23, "sex": "女"}‘

原因:通常用post方式请求时是json数据,但如果有中文则显示有问题,因为中文用 unicode 编码,而默认却是用ASCII解析的,中文不在ASCII编码中,所以不能显示中文。 

json数据转字典:In [25]: j                                                                                                                                                                                                                                                                    Out[25]: ‘{"name": "mary", "age": 21}‘

In [26]: result = json.loads(j)                                                                                                                                                                                                                                               

In [27]: result                                                                                                                                                                                                                                                               Out[27]: {‘name‘: ‘mary‘, ‘age‘: 21}

In [28]: type(result)                                                                                                                                                                                                                                                         Out[28]: dict

4.列表和元组的转换

元组 和 列表之间的转换

使用 list 函数 可以把 元组 转换成 列表

list(元组)

使用 tuple 函数 可以把 列表 转换成 元组

tuple(列表)

#列表转换元组
num_list = [1,2,3,4,5]
print(type(num_list))
print(num_list)
num_tuple = tuple(num_list)
print(type(num_tuple))
print(num_tuple)

#元组转换列表
num_tuple_01 = (1,2,3,4,5)
print(type(num_tuple_01))
print(num_tuple_01)
num_list_01 = list(num_tuple_01)
print(type(num_list_01))
print(num_list_01)

5.使用labana输出两数相乘

value=lambda x,y:x×y
print(value(1,2))

6.一行代码输出1-100之和

Python 3.5.2 (default, Nov 12 2018, 13:43:14)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.

range左闭右开区间
>>> total=sum(range(101))
>>> print (total)
5050

7.[[1, 2], [3, 4], [5, 6]]输出为[1, 2, 3, 4, 5, 6]

#1)利用推导式运行过程:for i in a ,每个i是【1,2】,【3,4】,【5,6】,for j in i,每个j就是1,2,3,4,5,6,合并后就是结果

a=[[1,2],[3,4],[5,6]]
x=[j for i in a for j in i]    #这个的解析过程是 从a中取出每一个值付给i,然后从i中取出每一个 值复制给j 然后输出j的结果
print(x)       ==>[1, 2, 3, 4, 5, 6]

8.列表去交集和并集

 求多个list的交集

1 a = [0,1,2,3,4]
2 b = [0,2,6]
3 c = [-1,2,5,8]
4 r = list(set(a).intersection(b,c))
5 print(‘r -->‘, r)

 求多个list的并集

1 a = [0,1,2,3,4]
2 b = [0,2,6]
3 c = [-1,2,5,8]
4 r = list(set(a).union(b,c)) # 求多个list的并集
5 print(‘r -->‘, r)   # 输出:r --> [0, 1, 2, 3, 4, 5, 6, 8, -1]"""

求多个list的差(补)集 - 即获取特定1个list中有,其他list都没有的元素
1 a = [0,1,2,3,4]
2 b = [0,2,6]
3 c = [-1,2,5,8]
4 r = list(set(a).difference(b,c)) # 求特定1个list(a)中有,其他list(b、c)都没有的元素"""
5 print(‘r -->‘, r)   # 输出:r --> [1, 3, 4]"""

list基本操作



 1 list = [1, 2, 3]
 2 list.append(5)
 3 print(list)
 4
 5 list.extend([6, 7])  # extend是将可迭代对象的元素依次加入列表
 6 print(list)
 7
 8 list.append([6, 7])  # append是把传入的参数当成一个元素加入列表
 9 print(list)
10
11 list.reverse()  # 元素翻转,注意不能将这个操作赋给一个变量,此操作是对list本身操作,即list自身发生变化
12 # l=list.reverse() l为空,没有得到list翻转后的值
13 print(list)
 

原文链接:https://blog.csdn.net/J_z10/article/details/79247533

原文地址:https://www.cnblogs.com/1314520xh/p/12154229.html

时间: 2024-10-20 00:55:33

odoo前后端交互详解的相关文章

写给刚入门的前端工程师的前后端交互指南

转自原文 写给刚入门的前端工程师的前后端交互指南 作为刚接触前端的不久的童鞋,大家都会兴奋于CSS和JS所带来漂亮界面,然而,前端工程师除了UI重构外,还有非常重要的职责在正确的区域渲染出服务端的数据.毕竟,我们要构建一个大的web应用,必然不是普普通通的静态页面构成. 下文将罗列将来前端工程师应该必备的同后端打交道的常用技能. 服务端渲染 谈起服务端渲染,对于动态服务而言,这个世界上跑的大多数页面都经历过服务端的数据渲染,接口->前端赋值->模版渲染 .这一切都在服务器完成,我们查看源码时候

网页前后端交互示例

对于网页开发而言,网页与服务器之间的数据交互是很频繁的,至关重要的一件事情.但是对于很多的初学者来说,这就成了一个不可逾越的难点问题,本篇博客将从一个初学者的关点讲解其中一种交互方式,此方法经过本人验证有效,并附有代码. 首先要实现网页前后台程序的交互需要安装后台框架,本人安装的框架为wamp(windows+apache+mysql+php).安装程序可以通过我在百度网盘上的分享链接下载http://pan.baidu.com/s/1cIKb8a 提取码是cnfh.至于安装过程中的配置可以参考

浅谈前后端交互

首先,关于接口文档--由后台设计修改(前端是接口文档的使用者) 其次,前后端交互的数据,格式是:json,(xml不多了) 重要的是,前后端如何交互??--接口地址+前端请求的参数+后台返回的参数 1.接口地址: 2.前端请求的参数: 形式:get/post(get从指定服务器提取数据,post将数据提交给指定服务器): 所有前端url后面的参数都是辅助后台数据查询的:若不需要参数,则后台会直接将url给前端: 注:为什么需要在请求的时候传入参数??--后台在查询数据库的时候需要按条件查询. 3

初识 vue —— 最简单的前后端交互示例

一.初识 vue 时的困惑 最近想学一门前端技术防身,看到博客园中写 vue 的多,那就 vue 吧.都说 vue 的官方教程写得好,所以我就从官方教程开始学习.官方教程说"Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用."但是这个概念是个什么鬼?还是让人一头雾水嘛.而且我一开始也没有搞清楚 vue 的定位,只知道它是一个前端库,但是确实不知道它的优势是什么,还以为它是一个学会就能一劳永

SSM-网站后台管理系统制作(4)---Ajax前后端交互

前提:Ajax本身就为前后端交互服务的,实现功能:用户输入信息,实时判断用户的情况,这也是现在登录界面普遍流行的做法.前端js通过注释识别Controller层,该层查询返回,和之前Google验证码有点像. 学习教程:http://how2j.cn/ 菜鸟教程 上面都有讲解, 前端Ajax代码 1 </script> 2 3 <script language="javascript" type="text/javascript"> 4 $(

百度ueditor的图片上传,前后端交互使用

百度ueditor的使用 一个文本编辑器,看了网上很多文档写的很乱,这里拾人牙慧,整理下怎么使用. 这个东西如果不涉及到图片附件上传,其实很简单,就是几个前端文件,直接引用,然后配置下ueditor.config.js即可.这里就不多说. 至于图片上传,ueditor 设计的时候是考虑和后端交互的,所以会看到可以下载什么php,java版本,还有很多网上会说道有什么后端配置文件,改那改这的,但是实际上后端存储业务是按照公司实际来的,实践起来并不顺利. 本文重点讲述的只用前端文件和ueditor.

Vue-CLI项目-axios模块前后端交互(类似ajax提交)

08.31自我总结 Vue-CLI项目-axios前后端交互 一.模块的安装 npm install axios --save #--save可以不用写 二.配置main.js import axios from 'axios' Vue.prototype.$axios = axios; 三.使用 created() { // 组件创建成功的钩子函数 // 拿到要访问课程详情的课程id let id = this.$route.params.pk || this.$route.query.pk

前后端交互模型(一个面试题引发的思考总结)

客户端和服务端的交互 面试题: 当用户在地址栏中输入网址,到最后看到页面,中间都经历了什么? (引出前后端交互模型的内容) 客户端 =======> 服务端 (request请求阶段) 服务端 <======= 客户端 (responese响应阶段) 1.URL地址解析 2.DNS域名解析(DNS服务器) 3.和服务器建立TCP连接 (三次握手) 4.把客户端信息传递给服务器(发送HTTP请求) 5.服务器得到并处理请求(HTTP响应内容) 6.客户端渲染服务器返回的内容 7.和服务器端断开T

前后端交互之封装Ajax+SpringMVC源码分析

为什么需要封装呢?因为用的多,我想将其封装成函数,当我想用它时,只需将那个函数对应的js文件引入即可,而不要重复写很多相同代码,利于开发效率的提高. 无论是$.ajax或$.post.$.get等,在开发中是经常用到的.再比如一些前端框架,例如easyui.ext.js等,ajax也是封装的. 编程的世界,封装无处不在. 具体js代码如下: /** * 增删改通用ajax请求 * @param type * @param url * @param datatype * @param conten