之前分析route方法的时候,可以看到中间会调用add_url_rule方法,add_url_rule方法和route方法一样属于Flask这个类的。

add_url_rule方法主要用来连接url规则。具体工作方法和route类似。如果提供了视图函数,它将会和endpoint名字一起被注册

#装饰器使用方法:
@app.route('/')
def index():
pass # 等同与下面这种方法:
def index():
pass
app.add_url_rule('/', 'index', index) If the view_func is not provided you will need to connect the endpoint
to a view function like so::
# 如果视图函数没有被提供,需要用下面语法把视图函数和endpoint对应起来
app.view_functions['index'] = index
  def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None) # if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only ``GET`` as default.
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)
if isinstance(methods, string_types):
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
methods = set(item.upper() for item in methods) # Methods that should always be added
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.
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 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

源代码

参数解析:

  • rule: 一个字符串格式的url规则,如:"/login". 注:就是从route方法中调用add_url_rule是传递的rule
  • endpoint: url规则的名字,用来反向生成url使用,默认是视图函数的名字。注:如果是route方法调用的,则这个参数是route方法传递过来的endpont
  • view_func: 视图函数,当对应的endpoint名字被请求时需要调用的函数。注:如果时router方法点用的add_url_rule,则这个参数时router方法传递过来的f
  • options: 类似与分析route时候的options.这个options是跟随:class:`~werkzeug.routing.Rule` object定义的,后面会分析这个对象中的具体参数,但有一个methods参数默认是只监听get方法。注:如果是router方法点用的add_url_rule,则这个参数时router方法传递过来的options函数

函数体解析:

   def add_url_rule(self, rule, endpoint=None,  view_func=None, **options):
if endpoint is None:
# 如果没有提供endpoint参数,则默认用view_func的名字
endpoint = _endpoint_from_view_func(view_func)
# 把endpoint参数添加到options里面
options['endpoint'] = endpoint
# 从options中pop出methods参数,并把值赋给methods变量,如果没有则置为None
methods = options.pop('methods', None)
# moehods的值为None的情况下
if methods is None:
# 如果view_func函数中有这个methods参数,则使用view_func中的。如果没有则赋一个列表('GET',)给methods
methods = getattr(view_func, 'methods', None) or ('GET',)
# 如果methods是字符串类型
if isinstance(methods, string_types):
# 抛出一个异常:methods需要是一个可以迭代的字符串
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
# 把methods里面的item都改成大写
methods = set(item.upper() for item in methods) # 在view_func里面定义了一个属性required_methods = ()
# 作用:用来定义一些必须的方法,配合provide_automatic_options使用
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.
# 在view_func里面定义了一个属性provide_automatic_options = None
# 作用:用于禁用和强制启用一些自动选项
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None) # 判断provide_automati_options是否为None
if provide_automatic_options is None:
# 如果OPTIONS字符串没有在methods里面
if 'OPTIONS' not in methods:
# 则把provude_automatic_options改为True,并把OPTIONS添加到required_methods里面
provide_automatic_options = True
required_methods.add('OPTIONS')
# 如果OPTIONS在methods里面,则把provide_automatic_options设置为False
else:
provide_automatic_options = False # 合并required_methods和methods这两个集合到methods里面
methods |= required_methods # 创建路由规则
# 调用url_rule_class方法,由于在Flask类的全局变量中定义了:url_rule_class = Rule, Rule是werkzeug/routing.py里面的一个类
# 也就是相当于实例化了Rule得到了rule对象,具体实例化后的结果请看Rule源码分析
rule = self.url_rule_class(rule, methods=methods, **options)
# 把provide_automatic_options属性添加到rule对象里面
rule.provide_automatic_options = provide_automatic_options # 在Flask类的__init__里面定义了self.url_map = Map(),Map是werkzeug/routing.py里面的一个类
# self.url_map相当与实例化了Map,.add则是调用了Map类里面的add方法
# 具体运行结果,请参考Map源码分析,以及Map源码中的add方法分析
self.url_map.add(rule)
# 如果提供了view_func
if view_func is not None:
# 在flask类的__init__里面定义了self.view_functions = {},
# 从字典里面取endpoint值并赋值为old_func,(endpoint是传递的参数,默认为视图函数名)
old_func = self.view_functions.get(endpoint)
# 如果old_func有值,并且不等于view_func
if old_func is not None and old_func != view_func:
# 则抛出异常:视图函数映射被一个已经存在的函数名重写了
# 也就是说已经存在了一个endpoint:old_func的映射,但是old_fun却不是view_func,也就是说endpoint重复了
raise AssertionError('View function mapping is overwriting an '
'existing endpoint function: %s' % endpoint)
# 添加视图函数与endpoint映射到view_functions字典里面
self.view_functions[endpoint] = view_func

flask/app.py-add_url_rule源码分析的更多相关文章

  1. FastText总结,fastText 源码分析

    文本分类单层网络就够了.非线性的问题用多层的. fasttext有一个有监督的模式,但是模型等同于cbow,只是target变成了label而不是word. fastText有两个可说的地方:1 在w ...

  2. Python 日志打印之logging.getLogger源码分析

    日志打印之logging.getLogger源码分析 By:授客 QQ:1033553122 #实践环境 WIN 10 Python 3.6.5 #函数说明 logging.getLogger(nam ...

  3. flask框架(三)——路由系统route转换成add_url_rule及源码分析

    这节我们不用@app.route来写路由,而是通过add_url_rule 传统写法  (<int:nid>传递int类型参数,endpoint是取别名) @app.route('/det ...

  4. Flask系列之源码分析(一)

    目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...

  5. flask源码分析

    本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...

  6. Flask系列10-- Flask请求上下文源码分析

    总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...

  7. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  8. Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析

    Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...

  9. Flask框架 (四)—— 请求上下文源码分析、g对象、第三方插件(flask_session、flask_script、wtforms)、信号

    Flask框架 (四)—— 请求上下文源码分析.g对象.第三方插件(flask_session.flask_script.wtforms).信号 目录 请求上下文源码分析.g对象.第三方插件(flas ...

随机推荐

  1. CSS清除浮动方法集合

    CSS清除浮动方法集合 一.浮动产生原因   -   TOP 一般浮动是什么情况呢?一般是一个盒子里使用了CSS float浮动属性,导致父级对象盒子不能被撑开,这样CSS float浮动就产生了. ...

  2. org.slf4j:slf4j-api:添加日志管理

    org.slf4j:slf4j-api:添加日志管理 转 https://blog.csdn.net/wolfking0608/article/details/77855624   一个好的程序, 完 ...

  3. c++调用动态库失败解决办法

    c++调用动态库失败解决办法 之前写好的程序今天早上过来发现在服务器上出错了,于是就各种查问题,整整一个早上外加下午两个小时都在查这个问题,最终被我找到了问题: 在程序中我发现LoadLibrary( ...

  4. OpenBLAS编译 Release x64 Win10 vs2015

    >------ 已启动生成: 项目: ZERO_CHECK, 配置: Release x64 ------ > Checking Build System > CMake does ...

  5. Python3入门(十三)——常用内置模块之时间日期模块datatime

    1.日期时间模块——datatime //其他模块例如time.calender等模块暂不展开 (1)获取当前时间:datatime.now(): from datetime import datet ...

  6. Spring cloud微服务安全实战-4-5搭建OAuth2认证服务器

    现在可以访问我们的认证服务器,应用我们已经配置好了. 下面配置让用户可以访问我的认证服务器.再来重写一个方法. EndpointConfigure端点的配置. authenticationManage ...

  7. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  8. Swift4.0复习扩展

    1.扩展计算式属性: 2.对方法进行扩展: /// 定义枚举类型Light, /// 它指定了基本类型String enum Light: String { case red = "red& ...

  9. 看烦了VS2012的黑白调调了吗?换

    VS2012的默认深色主题的确让整个IDE看起来很有气场,而且深色的主题保护眼睛,还是蛮不错的.但是看久了也会烦啊.虽然说重要的不是IDE看起来怎么样,而是写出来的代码质量怎么样,但一个好的环境也是会 ...

  10. shell每隔一秒钟就记录下netstat状态

    说明 木马可能类似随机发送心跳包的操作,随机sleep.对这类情况写好了一个监听shell脚本,每隔一秒钟就记录下netstat状态. 代码 #!/bin/bash #功能:用于定时执行lsof 和 ...