flask源代码笔记——路由
发布日期:2021-08-14 02:31:30 浏览次数:2 分类:技术文章

本文共 2448 字,大约阅读时间需要 8 分钟。

那flask是如何将路由与视图函数绑定的呢?在Flask类的内部是这样定义的:

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 decoratorself.view_functions = {}def add_url_rule(self, rule, endpoint, **options):    options['endpoint'] = endpoint    options.setdefault('methods', ('GET',))    self.url_map.add(Rule(rule, **options))self.url_map = Map()

可以看到,route定义了一个装饰品,通过add_url_rule方法将URL与视图函数的名字(即enpoint)绑定,并通过view_function字典将开发者定义的函数添加到视图函数里,形式为{ 函数名: 函数 }。也就是说,URL并不直接与处理函数绑定。URL是与endpoint绑定,而endpoint才与处理函数绑定。endpoint与处理函数通过view_fuction{}字典映射,这很好理解,不过URL与endpoint的绑定就需要多花点心思来理解了,因为引入了werkzeug中的Map和Rule。Map和Rule从字面上很容易理解 为“所有映射关系”和“产生一对新的映射关系”。

Flask类中dispatch_request()方法使用了view_fuction{}字典:

def dispatch_request(self):        try:        endpoint, values = self.match_request()        return self.view_functions[endpoint](**values)    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)

获取endpoint的关键在于match_request()方法:

def match_request(self):    """Matches the current request against the URL map and also    stores the endpoint and view arguments on the request object    is successful, otherwise the exception is stored.    """    rv = _request_ctx_stack.top.url_adapter.match()    request.endpoint, request.view_args = rv    return rv

这里的match方法是werkzeug中MapAdapter类定义的方法。

>>> m = Map([...     Rule('/', endpoint='index'),...     Rule('/downloads/', endpoint='downloads/index'),...     Rule('/downloads/
', endpoint='downloads/show')... ])>>> urls = m.bind("example.com", "/")>>> urls.match("/", "GET")('index', {})>>> urls.match("/downloads/42")('downloads/show', {
'id': 42})And here is what happens on redirect and missing URLs:>>> urls.match("/downloads")Traceback (most recent call last): ...RequestRedirect: http://example.com/downloads/>>> urls.match("/missing")Traceback (most recent call last): ...NotFound: 404 Not Found

这里展示了Map和Rule的主要几个功能:映射关系的添加、绑定和匹配。

总结一下路由匹配的过程:

  1. 通过@app.route或app.add_url_map()将URL和endpoint绑定,将endpoint和处理函数绑定。
  2. 将请求URL通过match方法取得endpoint及相关参数。
  3. 通过view_fuction{}字典获取endpoint对应的函数,将相关参数传入,进行处理。

转载于:https://www.cnblogs.com/tdkihrr/p/7554402.html

转载地址:https://blog.csdn.net/weixin_30703911/article/details/95428253 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java链接数据库的基本步骤
下一篇:CopyOnWriteArrayList源码解析

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年03月29日 02时42分15秒