在上一篇文章中,我们再启动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 variablessuch as the request HTTP headers, the source IP address andthe body as an io file.:param callable start_response: function provided by the WSGIserver that this application must call in order to send theHTTP 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 isextensible 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 responseraiseself._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 dispatchself.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方法都做了啥。