table of Contents
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'ok'
if __name__ == '__main__':
app.run()
From this simple code entry, to analyze what route@app.route('/')
route (): is a plus on the index () decorator
def route(self, rule, **options): # rule:匹配规则,options参数字典
def decorator(f):
endpoint = options.pop("endpoint", None) # 如果option中有endpoint就取出,否则endpoint=None
self.add_url_rule(rule, endpoint, f, **options) # f就是装饰器装饰的视图函数 index
return f
return decorator
Obtain information:
(1) can be specified when the reference transmission route endpoint = '别名'
, the route to be taken Endpoint alias, as reverse analysis, will be described later again. None for the time did not pass.
(2) it is the implementation of a method of matching add_url_rule adding a predetermined correspondence relationship with the view route to function
add_url_rule (): matching a predetermined correspondence relationship with the view to add a function to route
@setupmethod
def add_url_rule(self,rule,endpoint=None,view_func=None,provide_automatic_options=None,**options):
# 其中rule是必须要传入的,endpoint是别名,view_func是函数名
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func) # 如果没有别名就执行该函数,并且将视图函数当做参数传入了,稍后再看
options["endpoint"] = endpoint
methods = options.pop("methods", None) # 如果options中有methods则取出,否则为methods = None
# 如果methods为None的话,默认为view_func中的methods属性值,或者为('GET',)请求
if methods is None:
methods = getattr(view_func, "methods", None) or ("GET",)
# 如果methods是字符串类型,string_types=>(str, unicode),则抛出异常
if isinstance(methods, string_types):
raise TypeError(
"Allowed methods have to be iterables of strings, "
'for example: @app.route(..., methods=["POST"])'
)
# 循环遍历methods,并转成大写、去重
methods = set(item.upper() for item in methods)
required_methods = set(getattr(view_func, "required_methods", ()))
if provide_automatic_options is None:
provide_automatic_options = getattr(
view_func, "provide_automatic_options", None
)
if provide_automatic_options is None:
if "OPTIONS" not in methods:
provide_automatic_options = True
required_methods.add("OPTIONS")
else:
provide_automatic_options = False
methods |= required_methods
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) # 默认self.view_functions={},所以old_func=None
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 # 将 endpoint 与 view_func 对应。{endpoint:view_func}
One can see the source code is not ignorant of the above, the relevant part of the code to add a comment. Obtain information:
(1) methods are defined in the view mode request function, if it is not specified the default mode is get
(2) methods transmission parameter is a string type can not pass, should be provided: methods = ( 'post',), parameters are case insensitive, i.e., 'post' and 'POST' can be passed
(3) a value corresponding to the function name endpoint, such as endpoint = 'xxx': it is equivalent to the view taken an alias index function. If there is no endpoint, perform _endpoint_from_view_func(view_func)
, endpoint = function name
def _endpoint_from_view_func(view_func):
"""Internal helper that returns the default endpoint for a given
function. This always is the function name.
"""
assert view_func is not None, "expected view func if endpoint is not provided."
return view_func.__name__ # 返回的就是函数名
to sum up:
(1) the routing is performed essentially add_url_rule functions, it is also possible to add the routing function byapp.add_url_rule('/',endpoint='xxx',view_func=index)
(2) endpoint: to specify an alias, you do not specify a function name
(3) methods: request to specify the view function, it is not specified default to get method
(4) url_for: do the reverse route resolution alias
from flask import Flask, request,redirect,url_for
app = Flask(__name__)
app.debug =True
# @app.route('/')
def index():
return 'dasdk'
app.add_url_rule('/',endpoint='xxx',view_func=index) # 用来绑定路由
@app.route('/login',methods=['post','get'])
def login():
url = url_for('xxx') # 反向路由解析,url此时指向index视图函数
return redirect(url)
if __name__ == '__main__':
app.run()