参考:
Werkzeug库——routing模块
flask 源码解析:路由
odoo(8.0)源码
werkzeug(0.14.1)源码
flask(0.11.1)源码
一个web框架必须解决一个问题:当一个Request进入系统时,怎样去确定使用哪个函数或方法来处理。
Django自己处理这个问题。
Flask和Odoo(一个OpenERP)使用Werkzeug库(本身就是Flask的关联库)。
Werkzeug定义了三个类:
werkzeug.routing.Map
werkzeug.routing.MapAdapter
werkzeug.routing.Rule
Map的实例map存储所有的URL规则,这些规则就是Rule的实例rule。
一、Map
add(self, rulefactory)
该方法会将传入的rule,通过rule的bind方法来与map实例关联。并且,在map的_rules属性中插入rule实例,在_rules_by_endpoint属性中,创建rule.endpoint和rule实例的关联。
具体代码如下:
def add(self, rulefactory):
for rule in rulefactory.get_rules(self):
rule.bind(self)
self._rules.append(rule)
self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)
self._remap = True
由_rules_by_endpoint可见,一个endpoint可对应多个rule。
bind(self, server_name, ..., path_info, ...)
返回一个MapAdapter实例map_adapter。
bind_to_environ(self, environ, server_name=None, subdomain=None)
调用上述的bind方法,传入environ中的信息。比如说path_info,request_method等等。
二、MapAdapter
该类执行具体的URL匹配工作。
__init__(self, map, server_name, script_name, subdomain, url_scheme, path_info, default_method, query_args=None)
初始化时,会处理传入的map:
def __init__(self, map, ...):
self.map = map
match(self, path_info=None, method=None, return_rule=False, query_args=None)
通过传入的path_info(路径信息,若为None,则使用初始化时传入的path_info),和method(HTTP方法)来从self.map._rules中找到匹配的rule(通过调用rule.match(path, method)),从而返回rule的endpoint和一些参数rv。
dispatch(self, view_func, path_info=None, method=None, catch_http_exceptions=False)
调用match方法,如果找到了对应的rule,则会执行该rule对应的view_func(视图函数)。
三、Rule
继承自RuleFactory
__init__(self, string, defaults=None, subdomain=None, methods=None, build_only=False, endpoint=None, strict_slashes=None, redirect_to=None, alias=False, host=None)
string就是url,另两个关键关键参数是endpoint和methods。
get_rules(self, m