正则匹配路由
在 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转移到我的个人网站 http://www.kendny.cn, 欢迎关注并评论!