注册路由
一个 web 应用不同的路径会有不同的处理函数,路由就是根据请求的 URL 找到对应处理函数的过程。
在执行查找之前,需要有一个规则列表,它存储了 url 和处理函数的对应关系。最容易想到的解决方案就是定义一个字典,key 是 url,value 是对应的处理函数。如果 url 都是静态的(url 路径都是实现确定的,没有变量和正则匹配),那么路由的过程就是从字典中通过 url 这个 key ,找到并返回对应的 value;如果没有找到,就报 404 错误。而对于动态路由,还需要更复杂的匹配逻辑。
Flask
中,构建这个路由规则 的两种方法,这两种方法是等价的:
- 通过
@app.route()
装饰器 - 通过
add_url_rule(self, rule, endpoint=None, view_func=None, **options)
方法:rule
: url 规则字符串,endpoint
:要注册规则的 endpoint,默认是view_func
的名字view_func
:对应 url 的处理函数,也被称为视图函数
通过 @app.route()
装饰器:
@app.route('/')
def hello():
return "hello, world!"
通过 add_url_rule()
def hello():
return "hello, world!"
app.add_url_rule('/', 'hello', hello)
可以看到 route
方法内部也是调用 add_url_rule
所以注册路由也可以直接使用add_url_rule实现
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage.
"""
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
add_url_rule
核心代码如下:
def add_url_rule(
self,
rule,
endpoint=None,
view_func=None,
provide_automatic_options=None,
**options
):
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options
self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError(
"View function mapping is overwriting an "
"existing endpoint function: %s" % endpoint
)
self.view_functions[endpoint] = view_func