Flask 的 route 的原理如果大家去看 flask 库的第一个commit,可能会很好理解,现在的Flask 也是延续了这个设计,源码如下:
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. Example::
@app.route('/')
def index():
return 'Hello World'
"""
def decorator(f):
if 'endpoint' not in options:
options['endpoint'] = f.__name__
self.url_map.add(Rule(rule, **options))
self.view_functions[options['endpoint']] = f
return f
return decorator
在项目中生成 Flask 的实例 app 的时候,app 会初始化以下三个实例属性,可以将 url_rule 路由到应该执行的view_function(通过url_map匹配到正确的endpoint, 再通过endpoint找到应该执行的view_function):
- view_functions :存储格式为 {'endpoint': <view_function对象>}
- url_map :存储格式为 {Rule(rule, **options): 'endpoint'}
- url_rule_class 存储了 url 和 指定的请求方式,存储格式如下:
Rule '/hello' (HEAD, OPTIONS, GET)
代表 url 为 host/hello 的 允许请求方式有 HEAD, OPTIONS, GET
那么蓝图的 route 是怎么实现的呢?
蓝图中的路由规则是调用了app.add_url_rule来将规则添加到 view_functions 和 url_map中,格式为:
- view_functions {"%s.%s" % (self.blueprint.name, endpoint): <view_function对象>}
- url_map {Rule(rule, **options): "%s.%s" % (self.blueprint.name, endpoint)}
add_url_rule 的可传入参数如下:
def add_url_rule(
self,
rule,
endpoint=None,
view_func=None,
provide_automatic_options=None,
**options
):
ps:
- endpoint 默认为 view_function.name