Flask中路由模块的实现

在Flask中的路由功能主要通过修饰函数route实现,下面我们就来挖掘下route在源代码中是怎么分配视图函数的。

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

可以看出route是通过调用add_url_rule来添加路由功能的,endpoint负责与rule产生Rule类的,在add_url_rule中

    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

如果没有提供endpoint,_endpoint_from_view_function返回的是函数的__name__值作为这个函数的endpoint,后面设置了该试图函数支持的请求方法,之后产生Rule的实例,然后把这个实例添加到Map中,最后再记录endpoint和view_function的对应关系,以便将来得到请求时寻找到对应的视图函数。

其中的Rule和Map是在werkzeug所实现的。以下是Rule和Map的一般形式

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

Rule通过compile将rule转换成相对应的正则表达式如/all/page/<int:page>会被转换为r'/all/page/(?P<page>[0-9])'类似的形式,通过match会返回page的词典,也能基于提供的endpoint和dictory来构建相应的url,map则负责集合rule,调用map的bind方法会返回MapAdapter,这个类会处理多种重定向的情况以及调用视图函数。

转载于:https://www.cnblogs.com/steinliber/p/5173215.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值