OPENERP WEB端源码框架分析(逐步更新中...)
-
刚进入OPENERP和PYTHON OPENERP 不到一个月 对于我来说还是一个新人 这里首先应该感谢 我们这个论坛 我通过看了里面的 知识库,一些帖子,OpenERP应用和开发基础一至六章 等 ,使我可以快速的进步可以熟练的应用OPENERP, 但我发现关于源码分析的内容比较少 ,当然这个贴子没有什么很高技术含量 是为像我一样刚进入OPENERP的新人能快速理解OPENERP的框架结构 当我刚接触OPENERP的时候 就有一个疑问它是怎么运作的,内部是怎么实现的 就像你买个电脑总想拆开看看里面到底是什么东西 好了废话就到这里吧 这个部分主要说一下 OPENERP WEB的源码架构分析
先借老肖的图来看看
[attach]423[/attach]
OPENERP WEB端 与 SERVER端 通信是用 XML-RPC 和 NET-RPC ,用CHERRYPY来实现页面的响应 ,用MAKO模板技术来展现页面的内容
如果你以前做过B/S项目的话 你会发现怎会这样 为什么WEB项目里面什么业务逻辑都没有 所以业务逻辑怎么都在OpenERP Server(业务数据库)里面
我个人理解OpenERP Server为业务数据库 像我在07年做B/S的时候会写个页面放进去个GRID控件 指定的数据源 从数据库里读出个datatable出来 加载到GRID里 就是写个页面 然后从数据库加载数据显示出来,而OPENERP却是不用你写页面 它直接从OPENERP SERVER(业务数据库)里加载页面数据和业务数据 一起到WEB端, 再由WEB端生成页面显示业务数据同时响应用户的交互式的操作 这就像 你再好的法拉利汽车你和变形金刚大黄蜂比XML-RPC 和 NET-RPC 在OPENERP里的作用 让我想起 三国演义里的空城计 OPENERP WEB端就是那个阳平关城 XML-RPC和NET-RPC就是 诸葛亮弹吉他的两只手 从诸葛亮的心理(OPENERP SERVER端)弹出来 把一个空城弹的是百万兵马 呵呵 IE用户就都是司马懿了 (看上面的图用的还是电吉他)
关于 XML-RPC 和 NET-RPC基本用法 请看看这里 www.shine-it.net/viewthread.php?tid=927&extra=page%3D1
在以后的时间会详细分析 XML-RPC 和 NET-RPC 在OPENERP 的源码OPENERP WEB端 用的HTTP服务器用的是 Cherrypy 的内建 HTTP 服务器
[检测到链接无效,已移除] 打开主菜单页面 [检测到链接无效,已移除] 打开某一个菜单项的页面(TREE形式的就是GRID查询的形式) ,后面都会有一些参数 例如?model=ir.ui.menu&id=84 [检测到链接无效,已移除] 打开一个表单 这里的参数会很多 例如 ?model=res.partner&id=2&ids= 等 很多参数
我们可以从python的交互式解析器里运行[attach]424[/attach]
先 停掉 OPENERP WEB端的服务 不然会端口已占用的错误的
[attach]425[/attach]
下面是 我登陆 然后进入业务伙伴的TREE里的 访问日志信息
[attach]426[/attach]
OPENERP WEB端的 HTTP响应 基本就那么几个还有很多这里就不一一列举 可以自己尝试一些
这里的 menu ,tree/open,form/view 都不是实际的页面 而是类 通过 Cherrypy 可以把访问的路径比如http://localhost:8080/menu 映射到 类里的方法 ,然后方法返回基于MAKO模板生成的页面下面 用一个实例来说话最有说服力了
首先看一下这个类 [attach]428[/attach]
它是日志的装饰器(decorater) 我们为了调试方便 做点小小的修改
把原来的36行 def profile(name, log=[], cb=None): 改成了新的 def profile(name, log=[], cb=None,result=False): 加了一个有默认值的参数
result=False 的意思是是否输出函数返回值
把原来的98行 logger.info(message(func, *args, **kw), extra=dct) 改成了新的
if result:
logger.info(message(func, *args, **kw)+"result="+str(res), extra=dct)
else:
logger.info(message(func, *args, **kw), extra=dct)
这就OK了
然后在shortcuts.py模块里的 def default(self): 上面加上日志的装饰器 @profile("leetaizhu", log=[0],cb=None,result=True)
第一个参数是日志的文件名 ,第二个是 被装饰的函数的参数 log=[0] 里的0代表self 具体看上面的图片里的注释
[attach]429[/attach]
最后 一个 要改下配置文件 把注释去掉
# Simple code profiling
server.profile_on = True
server.profile_dir = "profile"然后重新启动一下OPENERP WEB端的服务
对个搞了半天 具体要测什么呀
[attach]431[/attach]
点击 SHORTCHTS链接
[attach]433[/attach]
下面是点击之后的日志信息 第一行 result=之后的就是 那个函数的返回值了
[attach]432[/attach]
通过对比它和 点击右键时的HTML源码是一样一样一样的!
[attach]434[/attach]MAKO 模板界的小鲨鱼的 很是厉害 它还是混血儿 它爸是大蟒PYTHON(呵呵) 这里找到一个很好的教程 www.cnblogs.com/rchen/archive/2007/06/15/mako_doc_translation_1.html
下面就看看 OPENERP WEB端的 MAKO 的使用吧 ...
[attach]435[/attach]
[attach]436[/attach][[i] 本帖最后由 leetaizhu 于 2010-3-15 00:13 编辑 [/i]]
-
感谢leetaizhu的详细描述,让我们掌握了用profile装饰器来输出log调试信息的方法。
这里英雄辈出,牛人们都从牛年放假回来了:lol -
看了楼主的分析,对WebClient了解了不少。只是对于Cherrypy如何将http://localhost:8080映射到Root方法里的login函数的比较好奇。所以就跟踪了一下,对于Cherrypy多了一点了解:
在openerp-web.py中调用
try:
start()
进入了commands.py中的:
def start():
"""Start the CherryPy application server."""parser = optparse.OptionParser(version=release.version) parser.add_option("-c", "--config", dest="config", help="specify alternate config file", default=get_config_file()) (opt, args) = parser.parse_args() setup_server(opt.config)
在setup_server函数中,对于cherrypy所需的config文件中的global和app的配置项进行了设置。接着,调用了
from openerp.controllers.root import Root
app = cherrypy.tree.mount(Root(), '/', app_config)
在这里,cherrypy.tree.mount函数就将Root对象、站点根装载点和配置文件写入了cherrypy再往后,调用了
from openerp import rpc
rpc.initialize(host, port, protocol, storage=CPSessionWrapper())
将配置项写入了rpc对象中,在其中,我们就可以看到所谓的NET-RPC和XML-RPC网关的初始化。这样就可以把前后端给联系起来了。但愿能有点帮助。