Flask源码:route
2021/8/6 1:37:25
本文主要是介绍Flask源码:route,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
研究一下Flask的app.route到底做了什么工作
route
@index.route('/') def hello_world(): # import inspect, json # print(json.dumps([str(fi.frame) for fi in inspect.stack()], indent=4)) return render_template('test_jinja.html'), 404
跟踪route
装饰器
# Scaffold类中 def route(self, rule: str, **options: t.Any) -> t.Callable: def decorator(f: t.Callable) -> t.Callable: endpoint = options.pop("endpoint", None) self.add_url_rule(rule, endpoint, f, **options) return f return decorator
发现其实只是调用了一个add_url_rule
所以我们可以通过add_url_rule
直接添加路由而不使用装饰器。
app.add_url_rule(rule, endpoint, f, **options)
跟踪add_url_rule
#Scaffold类中 @setupmethod def add_url_rule( self, rule: str, endpoint: t.Optional[str] = None, view_func: t.Optional[t.Callable] = None, provide_automatic_options: t.Optional[bool] = None, **options: t.Any, ) -> None: raise NotImplementedError
这个函数在Scaffold
中是空的,看来在Flask
有它的override
跟进Flask.add_url_rule
# Flask类中 @setupmethod def add_url_rule( self, rule: str, endpoint: t.Optional[str] = None, view_func: t.Optional[t.Callable] = None, provide_automatic_options: t.Optional[bool] = None, **options: t.Any, ) -> None: # 获取endpoint,如果为空则取函数名 if endpoint is None: endpoint = _endpoint_from_view_func(view_func) # type: ignore # 设置endpoint options["endpoint"] = endpoint # method为HTTP动作的元组或列表,如['GET', 'POST'] methods = options.pop("methods", None) # 如果为空,则寻找这个view_func的methods属性 # 否则默认是('GET'),即默认只处理GET动作 if methods is None: methods = getattr(view_func, "methods", None) or ("GET",) # method不能是字符串 if isinstance(methods, str): raise TypeError( "Allowed methods must be a list of strings, for" ' example: @app.route(..., methods=["POST"])' ) # 将methods的所有元素转为大写,即能够在methods参数中使用小写,如('get', 'post'),因为这里有转换 methods = {item.upper() for item in methods} # Methods that should always be added # 必须要添加的HTTP动作 required_methods = set(getattr(view_func, "required_methods", ())) # starting with Flask 0.8 the view_func object can disable and # force-enable the automatic options handling. # 是否自动添加options动作 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 # Add the required methods now. # 将两个集合合并 methods |= required_methods # 创建规则 rule = self.url_rule_class(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options # type: ignore # 将规则添加到url_map中 self.url_map.add(rule) if view_func is not None: # 不同视图必须有不同的endpoint,即endpoint唯一,是不同视图的标识符 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" f" endpoint function: {endpoint}" ) # 将视图存入view_functions self.view_functions[endpoint] = view_func
总结
这个函数最终处理下来主要做了两件事
- 实例化一个
url_rule_class
类(Rule
类),并存入url_map
(一个为url服务的Map
类型) - 将
view_func
存入view_functions
(一个字典类型)
这篇关于Flask源码:route的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)