- 转换器的作用:是对url地址的限制
- 自定义转换器的语法:
自定义转换器的步骤:
1. 自定义转换器必须继承BaseConverter类,自定义转换器需要重写父类的init方法,重点是注意参数。
2. 在调用时,《re(“.“):file_name》,会把 . 作为参数传给*args,再传给父类的regex作为正则,匹配url,匹配上的内容作为参数file_name传给视图函数。
3. 自定义转换器需要注册,re是转换器调用的是key
#coding:utf-8from flask import Flaskfrom werkzeug.routing import BaseConverterapp = Flask(__name__)class RegexConverter(BaseConverter):def __init__(self,url,*args):super(RegexConverter,self).__init__(url)self.regex = args[0]app.url_map.converters['re'] = RegexConverter@app.route('/send/')def send_sms(mobile):return 'send sms %s' %mobileif __name__ == '__main__':app.run(debug=True)
更新于 2018.8.3
关于其中的 to_python 方法
首先是实现一个简单的路由转换器去匹配三位数字,代码如下:
from flask import Flask
from werkzeug.routing import BaseConverterclass RegexConverter(BaseConverter):regex = r'[0-9]{3}'app = Flask(__name__)app.url_map.converters['re'] = RegexConverter@app.route('/')
def hello_world():return 'Hello World!'@app.route('/order/')
def order(order_id):print(type(app.url_map))return 'order %s' % order_idif __name__ == '__main__':app.run(debug=True)
在这个基础上,我们要对 BaseConverter 里面的三个方法进行重写:
__init__ to_python to_url
在查看了源码之后,我们发现 NumberConverter 是可以实现匹配任意长度的数字的。
NumberConverter 是 IntegerConverter 的父类 。在 NumberConverter 的 to_python 方法里面完成了对字符串转换为 数字的装换过程 。
在进行视图函数之前,会首先进入到 转换器的 to_python 里面。在正则匹配之后,视图函数调用之前,会进入 to_python
方便下一步的处理。第一次匹配的结果,如果我们想做进一步的处理,就可以写在 to_python 这个函数里面 方便对其进行下一步的处理。
通过断点调试,我们发现我们转出的不是一个 int 类型,而是一个py2 字符串类型。
所以进一步的改进方案就是重写 to_python 方法,添加:
返回值就是我们做正则匹配的值。
def to_python(self, value):value = int(value)return value
这时候:
我们不一定要重写 to_python, 看我们的实际需要 ……
关于其中的 to_url 方法
如果有时候我们得不到预期的结果,我们可以尝试清理一下 COOKIE 缓存 …
我们回到一个简单的模型,如下:
通过断点调试我们发现我们的系统只进入了 to_python
而没有进入 to_url
。这是因为 to_url 是 flask 重定向的时候使用的。
to_url
是在开始匹配之前就调用,将收集到的 order_id
传进去 ,第一次进行处理 ,比如在 BaseConverter 里面就进行了 基本的字符串编码。也是为了方便 to_python 的处理。它跟匹配成功与否并没有关系。我们查看源码发现,发现 NumberConverter
的to_url 对位数进行了处理 ,不满指定的位数补上 0 。
简言之, 在开始匹配之后,匹配成功之前,对匹配出来的 order_id 做第一步的处理,是为了保证可以顺利进入 to_python 里面。无论在最终的重定向时最终的成功与否,都会被调用,打前战…目的是为了让 value 无限匹配 regex
使用自带的 int 转换器
from flask import Flask, redirect, url_for
from werkzeug.routing import BaseConverterapp = Flask(__name__)@app.route('/')
def hello_world():return 'Hello World!'@app.route('/order/')
def order(order_id):return 'order %s' % order_id@app.route('/demo')
def demo():return redirect(url_for('order', order_id='123'))if __name__ == '__main__':app.run(debug=True)
最终版本
from flask import Flask, redirect, url_for
from werkzeug.routing import BaseConverter
class RegexConverter(BaseConverter):"""自定义路由转换器,实现匹配三位数字"""def __init__(self, url_map, *args):super(RegexConverter, self).__init__(url_map)self.regex = args[0]def to_python(self, value):value = int(value)return valuedef to_url(self, value):value = int(value)value = '%03d' % valuereturn valueapp = Flask(__name__)
app.url_map.converters['re'] = RegexConverter
@app.route('/order/')
def order(order_id):return 'order %s' % order_id
@app.route('/demo')
def demo():return redirect(url_for('order', order_id='12'))if __name__ == '__main__':app.run(debug=True)
更新于 2018.8.28
(8)正则路由示例
在web开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要正则匹配。限制访问,优化访问。
导入转换器包
from werkzeug.routing import BaseConverter
自定义转换器并实现
自定义转换器
class Regex_url(BaseConverter):def __init__(self,url_map,*args):super(Regex_url,self).__init__(url_map)self.regex = args[0]app = Flask(__name__)
# 将自定义转换器类添加到转换器字典中
app.url_map.converters['re'] = Regex_url@app.route('/user/')
def hello_world(id):return 'hello %s' %id
自带几种转换器
DEFAULT_CONVERTERS = {'default': UnicodeConverter,'string': UnicodeConverter,'any': AnyConverter,'path': PathConverter,'int': IntegerConverter,'float': FloatConverter,'uuid': UUIDConverter,
}
联系方式
很少看评论
qq:2564493603
欢迎交流