Flask入门学习——自定义一个url转换器
我们知道,flask的url规则是可以添加变量部分的,这个参数变量是写在尖括号里的,比如:/item/<id>/
,如果需要指出参数的类型要符合<converter:vaiable_name>
格式的,其中,converter有几种类型:
- string:接受不含有‘/’的文本
- int:接受整数
- float:接受浮点型
- path:接受含有‘/’的文本串
- uuid:只接受uuid串
而当没有符合的转换器时,就需要自己定义一个转换器供我们使用,完成它只需要三步:
1.自定义转换器
2.将自定义的转换器添加到flask的应用中
3.使用转换器
现在,定义一个类似127.0.0.1:5000/flask+aaa
这样的。
import urllib.parse as par
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# 1.自定义转换器
class ListConverter(BaseConverter):
def __init__(self, url_map, separator='+'):
super(ListConverter, self).__init__(url_map) # 调用父类的构造方法
self.separator = par.unquote(separator) # 将自定义转换器参数保存在对象的属性中,flask回去使用这个
def to_python(self, value):
return value.split(self.separator)
def to_url(self, values):
return self.separator.join(super(BaseConverter, self).to_url(value) for value in values)
# 2.将自定义的转换器添加到flask的应用中
app.url_map.converters['list'] = ListConverter
# 3.使用
@app.route('/list1/<list:page_names>/')
def list1(page_names):
return 'Separator: {} {}'.format('+', page_names)
# 3.使用
@app.route('/list2/<list(separator=u"|"):page_names>/')
def list2(page_names):
return 'Separator: {} {}'.format('|', page_names)
if __name__ == '__main__':
app.run(debug=True)
当我们访问http://127.0.0.1:5000/list1/a+b/
和http://127.0.0.1:5000/list1/a|b/
就能实现同样的功能了。要注意:自定义转换器需要继承自BaseConverter类,并且设置to_python(把路径转换成一个Python对象)和to_url(把参数转换成符合url的格式)两个方法。
另一个转换器-----自定制正则路由匹配:
from flask import Flask,url_for
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# 定义转换的类
class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
:param value:
:return:
"""
return int(value)
def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
return val
# 添加到converts中
app.url_map.converters['regex'] = RegexConverter
# 进行使用
@app.route('/index/<regex("\d+"):nid>',endpoint='xx')
def index(nid):
url_for('xx',nid=123)
return "Index"
if __name__ == '__main__':
app.run()