flask v0.1 路由

路由,就是将URLFunction对应起来,
可以将URL作为key,将Function作为value.但是flask中并不是这么简单.

flask中构建路由有两种方法:
1.app.add_url_rule
2.@app.route()
@app.route()的本质是调用了app.add_url_rule

Basically this example::

    @app.route('/')
    def index():
        pass

Is equivalent to the following::

    def index():
        pass
    app.add_url_rule('index', '/')
    app.view_functions['index'] = index

app.add_url_rule有三个参数:
rule:url字符串
endpoint:的id
options:是werkzeug.routing.Rule的参数

def add_url_rule(self, rule, endpoint, **options):
    options['endpoint'] = endpoint
    options.setdefault('methods', ('GET',)) # 将默认的请求方法设置为`Get`
    self.url_map.add(Rule(rule, **options) 

可以看到,通过操作url_map也可以实现,url_map本质是werkzeug库中的Map对象,还调用了werkzeugRule对象.

from werkzeug.routing import Map, Rule
self.url_map = Map()

首先看Map

>>> m = Map([
...     Rule('/', endpoint='index'),
...     Rule('/downloads/', endpoint='downloads/index'),
...     Rule('/downloads/<int:id>', endpoint='downloads/show')
... ])
>>> urls = m.bind("example.com", "/")
>>> urls.match("/", "GET")
('index', {})
>>> urls.match("/downloads/42")
('downloads/show', {'id': 42})

Map的主要作用就是URLendpoint的映射,通过URL来找(match)endpoint.而如何通过endpointfunction则需要我们自己来实现,flask中是用字典来实现的

当我们写下:

@app.route('/')
def index():
    pass

首先是调用self.add_url_rule添加路由规则,endpointfunction的名字,这里是index,
然后在view_functions(dict)中添加,keyfunction的名字,valuefunction方法

def route(self, rule, **options):
    def decorator(f):
        self.add_url_rule(rule, f.__name__, **options)
        self.view_functions[f.__name__] = f
        return f
    return decorator

view_functionsflask初始化时创建的

self.view_functions = {}

而在处理请求的时候,也是直接在view_functions中根据endpoint来提取

    def dispatch_request(self):
        try:
            endpoint, values = self.match_request() # 根据url获得endpoint
            return self.view_functions[endpoint](**values) # 根据endpoint来调用方法
        except HTTPException, e:
            handler = self.error_handlers.get(e.code)
            if handler is None:
                return e
            return handler(e)
        except Exception, e:
            handler = self.error_handlers.get(500)
            if self.debug or handler is None:
                raise
            return handler(e)

最后补充werkzeug实现的match方法


def match(self, path):
    if not self.build_only:
        m = self._regex.search(path)
        if m is not None:
            groups = m.groupdict()

            result = {}
            for name, value in iteritems(groups):
                try:
                    value = self._converters[name].to_python(value)
                except ValidationError:
                    return
                result[str(name)] = value
            if self.defaults:
                result.update(self.defaults)

            return result

参考:
https://cizixs.com/2017/01/12/flask-insight-routing/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值