在上一篇文章中,我们再启动server的时候传入了一个对象odoo.http.root,看看这是何方神圣
odoo\http.py
这里定义了Application类, 二root是这个类的一个实例,注释说这是WSGI网关的入口点。通过调试跟踪,也确定了
odoo web请求最终都会发送给这个类去处理。
这个类实现了__call__函数,所以这个类可以当做函数去调用的。
def __call__(self, environ, start_response):
"""
WSGI application entry point.
:param dict environ: container for CGI environment variables
such as the request HTTP headers, the source IP address and
the body as an io file.
:param callable start_response: function provided by the WSGI
server that this application must call in order to send the
HTTP response status line and the response headers.
"""
看注释:
WSGI 应用的入口点:
environ 环境对象,一个字典,包括了HTTP请求头,IP地址以及body等信息
start_response: WSGI网关提供的回调函数,app处理完之后,需要调用这个函数返回响应信息。
这个函数根据将传入的environ封装成了httprequest对象,然后又将httprequest对象封装成了Request对象
最后根据不同的场景,生成了不同的response对象,然后返回 response(environ, start_response)。
三种场景:
一种是静态文件
需要DB
不需要DB
try:
if self.get_static_file(httprequest.path):
response = request._serve_static()
elif request.db:
with request._get_profiler_context_manager():
response = request._serve_db()
else:
response = request._serve_nodb()
return response(environ, start_response)
我们来看看比较常见的_serve_db()是什么逻辑?
这是request对象的一个方法,作用是在转发给 _serve_ir_http
之前准备好session并且加载ORM。
看看_serve_ir_http, 委托了对ir.http模型的大部分处理过程,这些都是对app的扩展。
def _serve_ir_http(self):
"""
Delegate most of the processing to the ir.http model that is
extensible by applications.
"""
ir_http = self.registry['ir.http']
try:
rule, args = ir_http._match(self.httprequest.path)
except NotFound:
self.params = self.get_http_params()
response = ir_http._serve_fallback()
if response:
self.dispatcher.post_dispatch(response)
return response
raise
self._set_request_dispatcher(rule)
ir_http._authenticate(rule.endpoint)
ir_http._pre_dispatch(rule, args)
response = self.dispatcher.dispatch(rule.endpoint, args)
# the registry can have been reniewed by dispatch
self.registry['ir.http']._post_dispatch(response)
return response
这个函数里已经可以调用orm了,ir_http = self.registry[‘ir.http’]这种写法也是一种常见的写法,获得对某一个模型的引用。
这个函数做了两件事:
1、根据请求路径获取到对应的路由规则 和 请求参数
rule, args = ir_http._match(self.httprequest.path)
2、请请求转发给路由规则中的处理函数,并将请求参数args也传递过去。
response = self.dispatcher.dispatch(rule.endpoint, args)
这篇文章到这里结束了,下一篇文章将解析一下 ir.http模型,看看它的_match方法都做了啥。