flask的route源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nidhoggz/article/details/82810552

Flask route的源码分析

flask的例子

from flask import Flask
app = Flask(__name__)

@app.route('/',methods=['GET'])
def index():
  return "hello world"

if __name__ == '__main__':
  app.run()


使用app.route装饰器,完成了url与视图函数的映射  
flask中使用了werkzuegRule类、Map类和MapAdapter类实现了{url:endpoint:view_func}的映射关系  
route装饰器在app.pyFlask类中

def route(self, rule, **options):
  def decorator(f):
    endpoint = options.pop('endpoint', None)
    self.add_url_rule(rule, endpoint, f, **options)
    return f
  return decorator


通过装饰器将url传入到add_url_rule当中的rule,methods**options关键字参数传入到add_url_rule

def add_url_rule(self, rule, endpoint=None, view_func=None,
                 provide_automatic_options=None, **options):

add_url_rule中,判断endpoint是否为空,为空调用_endpoint_from_view_func函数从视图函数中以字符串取出视图函数名,并将endpoint添加到字典options当中

if endpoint is None:
    endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None)

_endpoint_from_view_func函数返回视图函数的__name__属性

def _endpoint_from_view_func(view_func):
    assert view_func is not None, 'expected view func if endpoint '\
                                  'is not provided.'
    return view_func.__name__

rulemethods**options传入Rule类构造出一个rule对象,将该rule对象添加到url_map当中.其中 options['endpoint']=endpoint, rule=url . 通过routing.pyRule类建立了(url,endpoint,methods)的映射关系

rule = self.url_rule_class(rule, methods=methods, **options)
self.url_map.add(rule)

url_maprouting.pyMap类创建出来的一个对象,用来存储Rule的对象

self.url_map = Map()

Map内以列表来存储Rule的对象

url_map = Map([
                Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),
                Rule('/all/page/<int:page>', endpoint='all_entries')
            ])

add_url_ruleview_func就是app.route构造器修饰的视图函数,app.pyFlask类定义了view_functions为一个空字典,将view_func存入view_functions中,建立了{endpoint:view_func}的映射关系

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

Flaskurl_map存储了所有的(url,endpoint)映射关系;  
Flaskview_functions存储了所有的{endpoint:view_func}映射关系;  
至此,url与视图函数就通过endpoint映射起来了,请求时服务器对请求进行转发,解析得到url,通过MapAdapter类的match方法得到endpoint,再通过view_functions找到对应的视图函数,直接调用函数执行,就完成了一个完整的route.
 

猜你喜欢

转载自blog.csdn.net/Nidhoggz/article/details/82810552