Flask中正则匹配路由及路由转换器

正则匹配路由

​ 在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问

具体实现步骤为:

  • 导入转换器基类(BaseConverter):在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录
  • 自定义转换器:自定义类继承于转换器基类
  • 将自己的转换器添加到默认的转换器列表中
  • 使用自定义转换器实现自定义匹配规则

路由转换器: 匹配URL路由规则的对象

具体代码实现

# 1. 导入转换器基类
from werkzeug.routing import BaseConverter

# 2. 自定义转换器, 自定义类继承于转换器基类
class RegexConverter(BaseConverter):
    """自定义正则路由转换器"""
	
    def __init__(self, url_map, *args):
        super(RegexConverter, self).__init__(url_map)
        #取到第一个参数,给regex属性赋值
        # regex ="\d{6}"  #匹配6位数字
        self.regex = args[0]
        
# 3.将自己的转换器添加到默认的转换器列表中
app.url_map.converters['re'] = RegexConverter

# 使用自定义的转换器进行路由规则匹配, 转换器规则自定义并以参数传入
@app.route('/user/<re("[0-9]{4}"):user_id>')
def user(user_id):
    return "获取用户的id是:%s"%user_id

自定义转换器其他两个函数实现

​ 继承于自定义转换器之后,还可以实现 to_python 和 to_url 这两个函数去对匹配参数做进一步处理:

to_python

  • 该函数参数中的 value 值代表匹配到的值,可输出进行查看
  • 转换器匹配完成之后,对匹配到的参数作最后一步处理再返回,比如:转成 int 类型的值再返回:
class RegexConverter(BaseConverter):
    def __init__(self, url_map, *args):
        super(RegexConverter, self).__init__(url_map)
        # 将接受的第1个参数当作匹配规则进行保存
        self.regex = args[0]

    def to_python(self, value):
        return int(value)

运行测试,在视图函数中可以查看参数的类型,由之前默认的 str 已变成 int 类型的值

to_url:

  • 在使用 url_for 去获取视图函数所对应的 url 的时候,会调用此方法对 url_for 后面传入的视图函数参数做进一步处理
  • 具体可参见 Flask 的 app.py 中写的示例代码:ListConverter
from flask import Flask
from flask import redirect
from flask import url_for
from werkzeug.routing import BaseConverter

class ListConverter(BaseConverter):
    """自定义转换器"""
    regex = "(\\d+,?)+\\d$" # r"(\d+,?)+\d$" #匹配1,23,3,45这种模式的字符串

    def to_python(self, value):
        """当匹配到参数之后, 对参数做进一步处理之后,再返回给视图函数"""
        return value.split(',')

    def to_url(self, value):
        """
        在进行重定向使用url_for的时候,对视图函数传的参数进行处理,
        处理完毕之后以便能够进行路由匹配
        """
        result = ','.join(str(v) for v in value)
        return result
    
app = Flask(__name__)
app.url_map.converters['list'] = ListConverter

@app.route('/users/<list:user_ids>')
def demo2(user_ids):
    return "接收到的ids是: %s"%user_ids

@app.route('/demo3')
def demo3():
    return redirect(url_for('demo2', user_ids=[1,2,3,4,5]))


if __name__ == '__main__':
    app.run(debug=True)

说明: 当在浏览器中访问"http://localhost:5000/demo3"将重定向到视图函数demo2对应的路由,在此之前url_for函数的参数user_ids的参数会传到自定义转换器类to_url函数进行处理,处理完成后将result返回到demo2对应的路由转换器list, 在进行转换器规则校验前将result结果再又传入到ListConverter转换器的to_python进行处理,处理后的结果交给demo2视图函数进行返回;(注:整个过程可以通过pycharm断点查看);

系统自带转换器
DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}

猜你喜欢

转载自blog.csdn.net/u010268820/article/details/85805423
今日推荐