flask源码阅读 路由是怎么打通url -> endpoint -> view_function的

来源:互联网 发布:ides属于什么算法 编辑:程序博客网 时间:2024/06/10 01:42

第一步 把函数名和函数作为一个键值对添加到view_function字典里等待后用

  def route(self, rule, **options):     def decorator(f):            self.add_url_rule(rule, f.__name__, **options)     #把rule添加到url_map里面             self.view_functions[f.__name__] = f    #把函数注册到view_function字典里面,key是函数名,value是函数            return f        return decorator

第二步 根据客户端提的request请求中的url,在url_map里查找和匹配,如果没查到,就向里面添加,如果查到了就返回(endpoint, {}),这一步非常重要!它会在后面将我们和第一步联系起来

    def match_request(self):        """Matches the current request against the URL map and also     #在当前的URL map里面匹配请求发过来的url和        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

在当前的url_map里面匹配request请求发过来的url,参看下面的代码,如果匹配上了,就会返回一个两个值的元组,第一个值就是endpoint,第二个值暂为空,如果没有匹配上,返回404

>>> 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})>>> 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

第三步:如果我们查到了,则app在run过程中,会运行下面代码,我把关键点写在代码的注释里

    def dispatch_request(self):        """Does the request dispatching.  Matches the URL and returns the        return value of the view or error handler.  This does not have to        be a response object.  In order to convert the return value to a        proper response object, call :func:`make_response`.        """        try:            endpoint, values = self.match_request()                #匹配上了,把上面url对应的endpoint赋值给当前的endpoint            return self.view_functions[endpoint](**values)         #这一步在view_function字里找上一步赋值的endpoint,如果找到了,就返回以它(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)

上面三步,指明了为什么可以从客户端请求的url调用app的视图函数,整理一下思路

  1. 在url_map里匹配url和endpoint
  2. 如果在url_map里匹配到了url,就把它对应的endpoint发到view_function函数里去查找,如果找到到了,就返回视图函数 ,这样就把 url -> endpoint -> function() 联通了。

终于把这一关打通了,这里的参考资料帮助非常大!
http://cizixs.com/2017/01/12/flask-insight-routing
https://segmentfault.com/q/1010000003875420

0 0
原创粉丝点击