目录
route(): 就是一个加在 index()上的装饰器
add_url_rule(): 将匹配规定与视图函数的对应关系添加到路由
总结:
- from flask import Flask
- App = Flask(__name__)
- @App.route('/')
- def index():
- return 'ok'
- if __name__ == '__main__':
- App.run()
从这个简单的代码入口, 来剖析一下路由 @App.route('/')
route(): 就是一个加在 index()上的装饰器
- 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
获取的信息:
(1)route 传参时可以指定 endpoint = '别名',endpoint 是给这个路由取的别名, 用作反向解析, 稍后再会介绍. 没有传时为 None.
(2)主要是执行了 add_url_rule 方法将匹配规定与视图函数的对应关系添加到路由中
add_url_rule(): 将匹配规定与视图函数的对应关系添加到路由
- @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}
一眼看到上面的源码是不是懵, 在代码中相关的部分添加了注释. 获取的信息:
(1)methods 是定义该视图函数的请求方式, 如果没有指定就默认为 get 方式
(2)methods 传参是不能传字符串类型, 应该设置: methods=('post',), 参数不区分大小写, 即'post'与'POST'都可以传入
(3)将 endpoint 的值与函数名对应, 比如 endpoint='xxx': 则相当于是给视图函数 index 取了一个别名. 如果没有 endpoint, 执行_endpoint_from_view_func(view_func),endpoint = 函数名
- 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__ # 返回的就是函数名
总结:
(1)路由本质上就是执行了 add_url_rule 函数, 所以也可以通过该函数来添加路由 App.add_url_rule('/',endpoint='xxx',view_func=index)
(2)endpoint: 用来指定别名, 没有指定就用函数名字
(3)methods: 用来指定视图函数的请求方式, 没有指定就默认为 get 方法
(4)url_for: 通过别名来做反向路由解析
- 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')
- def login():
- url = url_for('xxx') # 反向路由解析, url 此时指向 index 视图函数
- return redirect(url)
- if __name__ == '__main__':
- App.run()
Flask 快速入门(3) - flask 路由的本质
来源: http://www.bubuko.com/infodetail-3216296.html