Flask_路由内部实现

路由内部实现+自定义转换器

from flask import Flask
app = Flask(__name__)


@app.route('/<int:news_id>',methods=['GET'])     #int:转换器
def detail(news_id):
    return 'ok'

@app.route('/',methods=['POST'])
def index():
    return 'index'

if __name__ == '__main__':
    print(app.url_map)                            # 输出app.url_map属性
    app.run()

在app中有个属性:url_map , 输出 app.url.map

Map([
    <Rule '/' (OPTIONS, POST) -> index>,
    <Rule '/<news_id>' (OPTIONS, GET, HEAD) -> detail>
    # Flask自动添加,用于静态文件的路径,当我们在setting文件中指定静态路径时,根据下面路由去查找静态文件。
    <Rule '/static/<filename>'(OPTIONS, GET, HEAD) -> static  
])

输出一个Map对象,Map对象里面有多个Rule对象,Rule对象里面的结构是< Rule '请求地址'  --->请求方法 ---> 对象的视图函数>

那么现在我们想看一下Map对象是什么?以及Rule对象里面是什么? 我们先输出Map对象的类型

  • if __name__ == '__main__':
        print(app.url_map)   # 输出app.url_map属性
        print(type(app.url_map))  #输出app.url_map对象的类型
        app.run()
    
    输出:
    <class 'werkzeug.routing.Map'>

    可以看出Map对象是werkzeug模块下面的一个对象,那么werkzeug是什么呢?

  • Flask框架由两个核心组成

    • werkzeug

    • jinjia2

Flask是在werkzeug模块的基础之上进行开发,werkzeug库的routing模块赋值实现URL解析,下面可以更好的看清Flask框架的组成。

进入Map类源码: 

class Map(object):
    default_converters = ImmutableDict(DEFAULT_CONVERTERS)    # 默认的转换器
    def __init__(self, rules=None, default_subdomain='', charset='utf-8',
                 strict_slashes=True, redirect_defaults=True,
                 converters=None, sort_parameters=False, sort_key=None,
                 encoding_errors='replace', host_matching=False):  
        self._rules = []                        # 创建了一个Rules列表对象
        elf._rules_by_endpoint = {}
        self._remap = True
        self._remap_lock = Lock()

        self.default_subdomain = default_subdomain
        self.charset = charset
        self.encoding_errors = encoding_errors
        self.strict_slashes = strict_slashes
        self.redirect_defaults = redirect_defaults
        self.host_matching = host_matching

        self.converters = self.default_converte rs.copy()   # 将默认的转化器copy到Map对象中
        if converters:
            self.converters.update(converters)

        self.sort_parameters = sort_parameters
        self.sort_key = sort_key

        for rulefactory in rules or ():
            self.add(rulefactory) 
  • 在第一行有定义默认的转换器,default_converters = ImmutableDict(DEFAULT_CONVERTERS) 
  • 进入DEFAULT_CONVERTERS
#: the default converter mapping for the map     
    DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }
  • 可以看出,当我们在url中设置了转化器int @app.route('/<int:news_id>',methods=['GET']) , int是什么东西?在这里就定义了
  •   'int':              IntegerConverter,  默认是字符串类型,那么IntegerConverter又是什么?进入IntegerConverter
class IntegerConverter(NumberConverter):   # 继承至NumberConverter

    regex = r'\d+'                # 正则表达式
    num_convert = int

也就是说int是一个正则表达式,当有请求url时,Flask会完成以下步骤

  1. 创建Rule对象 <Rule '/<int:news_id>' (OPTIONS, POST) -> index>
  2. 创建Map对象,将Rule对象添加进去Map([ <Rule '/<news_id>' (OPTIONS, GET, HEAD) -> detail>])
  3. 内置转换器,还会将装换器也添加进Map对象中
  4. 为app.url_map属性赋值

当有url请求时: 

  1.  验证正则表达式
  2.  验证请求方式
  3. 调用视图函数

 

自定义转化器

1, 定义一个类继承至 NumberConverter 

class IntegerConverter(NumberConverter):
	regex = r"\d+"    # 自定义正则
	num_convert = int 

2, app.url_map.converters['int']= IntegerConverter   将转换器添加至url_map对象的converters属性

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值