为了不影响阅读,源码放在最后,需要的可以自己阅读
本文主要验证flask自带转换器的使用规则
整理后的源码
class BaseConverter(object):
"""Base class for all converters."""
两个变量: regex weight
函数:
初始化
def __init__(self, map):
def to_python(self, value): # 匹配之后
# return value
# 该函数参数中的 value 值代表匹配到的值
# 匹配完成之后,对匹配到的参数作最后一步处理再返回,比如:转成 int 类型的值再返回
return int(value)
def to_url(self, value): # 匹配之前
return url_quote(value, charset=self.map.charset)
# 在使用 url_for 去获取视图函数所对应的 url 的时候,会调用此方法对 url_for 后面传入的视图函数参数做进一步处理
class UnicodeConverter(BaseConverter):
"""默认转换器 接收任何字符串"""
例::
规则( '/页/<页>'),
规则( '/<字符串(长度=2):LANG_CODE>')
:param map:the:class:`Map`。
:param minlength:字符串的最小长度。 必须更大
或等于1。
:param maxlength:字符串的最大长度。
:param length:字符串的确切长度。
class NumberConverter(BaseConverter):
"""IntegerConverter和FloatConverter的基类"""
变量:
map, fixed_digits, min, max
class IntegerConverter(NumberConverter):
"""此转换器仅接受整数值"""
支持:
固定位数
最小值
最大值
class FloatConverter(NumberConverter):
"""此转换器仅接受浮点值"""
支持:
最小值
最大值
# 默认转换器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
分割线=======================================
验证使用方法
代码演示:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
# # 默认转换器
# DEFAULT_CONVERTERS = {
# 'default': UnicodeConverter,
# 'string': UnicodeConverter,
# 'any': AnyConverter,
# 'path': PathConverter,
# 'int': IntegerConverter,
# 'float': FloatConverter,
# 'uuid': UUIDConverter,
# }
# UnicodeConverter 默认转换器
# @app.route('/demo1/<default(minlength=5, maxlength=10):page_id>') 最小长度 最大长度
# @app.route('/demo1/<default(length=6):page_id>') 固定长度
# @app.route('/demo1/<string(length=6):page_id>') default string 都可用于 UnicodeConverter
@app.route('/demo1/<string(minlength=5, maxlength=10):page_id>')
def demo1(page_id):
"""
UnicodeConverter
默认转换器 接收任何字符串
例::
规则( '/页/<页>'),
规则( '/<字符串(长度=2):LANG_CODE>')
:param map:the:class:`Map`。
:param minlength:字符串的最小长度。 必须更大或等于1。
:param maxlength:字符串的最大长度。
:param length:字符串的确切长度。
"""
return 'demo1--page_id is--%s' % page_id
# IntegerConverter(NumberConverter) 整数型转换器
# @app.route('/demo2/<int:page_id>') 整型
# @app.route('/demo2/<int(6):page_id>') 固定位数
# @app.route('/demo2/<int(min=10):page_id>') 最小值
# @app.route('/demo2/<int(max=10):page_id>') 最大值
@app.route('/demo2/<int(min=10, max=100):page_id>') # 取区间值
def demo2(page_id):
"""
此转换器仅接受整数值
支持:
固定位数
最小值
最大值
"""
return 'demo2--page_id is--%s' % page_id
# FloatConverter(NumberConverter) 浮点型转换器
# @app.route('/demo3/<float:page_id>') 浮点型
# @app.route('/demo3/<float(min=5):page_id>') 最小值
# @app.route('/demo3/<float(max=5):page_id>') 最大值
@app.route('/demo3/<float(min=5, max=10):page_id>') 取最小最大区间值
def demo3(page_id):
"""
支持:
最小值
最大值
:return:
"""
return 'demo3--page_id is--%s' % page_id
if __name__ == '__main__':
app.run(debug=True)
分割线=======================================
flask的转换器源码
class BaseConverter(object):
"""Base class for all converters."""
regex = '[^/]+'
weight = 100
def __init__(self, map):
self.map = map
def to_python(self, value):
return value
def to_url(self, value):
return url_quote(value, charset=self.map.charset)
class UnicodeConverter(BaseConverter):
"""This converter is the default converter and accepts any string but
only one path segment. Thus the string can not include a slash.
This is the default validator.
Example::
Rule('/pages/<page>'),
Rule('/<string(length=2):lang_code>')
:param map: the :class:`Map`.
:param minlength: the minimum length of the string. Must be greater
or equal 1.
:param maxlength: the maximum length of the string.
:param length: the exact length of the string.
"""
def __init__(self, map, minlength=1, maxlength=None, length=None):
BaseConverter.__init__(self, map)
if length is not None:
length = '{%d}' % int(length)
else:
if maxlength is None:
maxlength = ''
else:
maxlength = int(maxlength)
length = '{%s,%s}' % (
int(minlength),
maxlength
)
self.regex = '[^/]' + length
class AnyConverter(BaseConverter):
"""Matches one of the items provided. Items can either be Python
identifiers or strings::
Rule('/<any(about, help, imprint, class, "foo,bar"):page_name>')
:param map: the :class:`Map`.
:param items: this function accepts the possible items as positional
arguments.
"""
def __init__(self, map, *items):
BaseConverter.__init__(self, map)
self.regex = '(?:%s)' % '|'.join([re.escape(x) for x in items])
class PathConverter(BaseConverter):
"""Like the default :class:`UnicodeConverter`, but it also matches
slashes. This is useful for wikis and similar applications::
Rule('/<path:wikipage>')
Rule('/<path:wikipage>/edit')
:param map: the :class:`Map`.
"""
regex = '[^/].*?'
weight = 200
class NumberConverter(BaseConverter):
"""Baseclass for `IntegerConverter` and `FloatConverter`.
:internal:
"""
weight = 50
def __init__(self, map, fixed_digits=0, min=None, max=None):
BaseConverter.__init__(self, map)
self.fixed_digits = fixed_digits
self.min = min
self.max = max
def to_python(self, value):
if (self.fixed_digits and len(value) != self.fixed_digits):
raise ValidationError()
value = self.num_convert(value)
if (self.min is not None and value < self.min) or \
(self.max is not None and value > self.max):
raise ValidationError()
return value
def to_url(self, value):
value = self.num_convert(value)
if self.fixed_digits:
value = ('%%0%sd' % self.fixed_digits) % value
return str(value)
class IntegerConverter(NumberConverter):
"""This converter only accepts integer values::
Rule('/page/<int:page>')
This converter does not support negative values.
:param map: the :class:`Map`.
:param fixed_digits: the number of fixed digits in the URL. If you set
this to ``4`` for example, the application will
only match if the url looks like ``/0001/``. The
default is variable length.
:param min: the minimal value.
:param max: the maximal value.
"""
regex = r'\d+'
num_convert = int
class FloatConverter(NumberConverter):
"""This converter only accepts floating point values::
Rule('/probability/<float:probability>')
This converter does not support negative values.
:param map: the :class:`Map`.
:param min: the minimal value.
:param max: the maximal value.
"""
regex = r'\d+\.\d+'
num_convert = float
def __init__(self, map, min=None, max=None):
NumberConverter.__init__(self, map, 0, min, max)
class UUIDConverter(BaseConverter):
"""This converter only accepts UUID strings::
Rule('/object/<uuid:identifier>')
.. versionadded:: 0.10
:param map: the :class:`Map`.
"""
regex = r'[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-' \
r'[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}'
def to_python(self, value):
return uuid.UUID(value)
def to_url(self, value):
return str(value)
#: the default converter mapping for the map.
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}