flask源代码笔记——路由

那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 decorator

self.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/<int:id>‘, 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绑定,将
  2. endpoint和处理函数绑定。
  3. 将请求URL通过match方法取得endpoint及相关参数。
  4. 通过view_fuction{}字典获取endpoint对应的函数,将相关参数传入,进行处理。
时间: 2024-10-07 10:33:39

flask源代码笔记——路由的相关文章

flask源代码笔记——应用启动

flask一个最简单的demo是: from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello, World!' if __name__ == '__main__': app.run() run()方法启动了应用,那么run()背后都调用哪些类.方法和函数呢? 将相关代码汇总起来,如下: def run(self, host='localhost', port=5000, **o

Flask 蓝图进行路由分发

Flask 蓝图进行路由分发 Flask虽然说是一个轻型web框架,但也总不能用一个py文件写完全部view吧,所以我们要把路由分到不同的py文件中.这就需要用到蓝图了. 一 创建一个py文件 用于处理分过来的url,如创建music.py from flask import Blueprint music = Blueprint('music', __name__) @music.route("/") # 即 /music/ def roo(): return "music

第六篇 Flask中的路由系统

Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST"]) 为什么要这么用?其中的工作原理我们知道多少? 一.@app.route() 装饰器中的参数 methods :当前 url 地址,允许访问的请求方式 @app.route("/info", methods=["GET", "POST"]) d

Flask中的路由系统

Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST"]) 至于为什么这么使用,马上开始介绍 [email protected]() 装饰器中的参数 (1).methods: 当前url地址,允许访问的请求方式,默认支持"GET", 如果想加入新的请求方式,就必须加上"GET" USER = {"usernam

Flask 源代码阅读笔记

我认为我已经养成了一个坏习惯.在使用一个框架过程中对它的内部原理非常感兴趣,有时候须要花不少精力才 明确,这也导致了学习的缓慢,但换来的是对框架的内部机理的熟悉,正如侯捷所说,源代码面前,了无秘密.这也是 本文产生的直接原因. 一.flask session原理 flask的session是通过client的cookie实现的.不同于diango的server端实现,flask通过itsdangerous这个苦 将session的内容序列化到浏览器的cookie,当浏览器再次请求时将反序列化co

python web 部署:nginx + gunicorn + supervisor + flask 部署笔记

python web 部署 web开发中,各种语言争奇斗艳,web的部署方面,却没有太多的方式.简单而已,大概都是 nginx 做前端代理,中间 webservice 调用程序脚本.大概方式:nginx + webservice + script nginx 不用多说,一个高性能的web服务器.通常用来在前端做反向代理服务器.所谓正向与反向(reverse),只是英文说法翻译.代理服务,简而言之,一个请求经过代理服务器从局域网发出,然后到达互联网上服务器,这个过程的代理为正向代理.如果一个请求,

flask学习笔记1

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器. "微"(micro) 并不表示你需要把整个 Web 应用塞进单

11.2 Flask 配置文件,路由系统

配置文件系统 自定义配置文件 创建一个 setting.py 用于存放配置文件的相关属性 配置文件中可以进行分级继承来区分不同视图的配置文件设置 默认配置文件放在项目根路径下 # settings.py class Base(object): # 所有的都要有用到的配置更改 TEST = True class Dev(Base): DEV = True class Pro(Base): PRO = True 配置文件的设置方式 常用的是以下三种 # 方式1 直接更改 app.config["要更

Flask 学习之 路由

一.路由的基本定义 # 指定访问路径为 demo1 @app.route('/demo1') def demo1(): return 'demo1' 二.常用路由设置方式 @app.route('/user/<username>')   #常用的   不加参数的时候默认是字符串形式的 @app.route('/post/<int:post_id>')  #常用的   #指定int,说明是整型的 @app.route('/post/<float:post_id>') @a