美文网首页
Flask的route的源码分析

Flask的route的源码分析

作者: Nidhogg_3b5e | 来源:发表于2018-09-29 23:33 被阅读0次

    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

    GitHub

    相关文章

      网友评论

          本文标题:Flask的route的源码分析

          本文链接:https://www.haomeiwen.com/subject/lzlioftx.html