我想使用Flask来处理类型的网址:
http://localhost/aaa/bbb/ccc;x=1;y=10;z=11/ddd/
其中x,y,z如果不存在则可以应用合理的默认值(例如,ddd就可以)。
一种可能的方法是接收所有路径,然后手动拆分和处理:
@app.route('/')
@app.route('/<path:varargs>')
def hello(varargs = None):
if varargs:
print varargs
else:
print "Hello World"
有没有更优雅的方法来解决这个问题?
答案 0 :(得分:7)
不,开箱即用不支持此类网址。
但是,Flask使用Werkzeug library进行路由,该库支持为路径元素创建custom converters。提供转换器应该不会太难。这需要应用于特定的路径元素:
@app.route('/aaa/bbb/ccc<matrix(x=1, y=10, z=11):matrix_params>/ddd/')
注意传递参数的能力;这里x=1, y=10, z=11
是转换器的参数,指定矩阵参数的默认值。
转换器可能是:
from werkzeug.routing import BaseConverter, ValidationError
class MatrixConverter(BaseConverter):
def __init__(self, url_map, **defaults):
super(MatrixConverter, self).__init__(url_map)
self.defaults = {k: str(v) for k, v in defaults.items()}
def to_python(self, value):
if not value.startswith(';'):
raise ValidationError()
value = value[1:]
parts = value.split(';')
result = self.defaults.copy()
for part in value.split(';'):
try:
key, value = part.split('=')
except ValueError:
raise ValidationError()
result[key.strip()] = value.strip()
return result
def to_url(self, value):
return ';' + ';'.join('{}={}'.format(*item) for item in value.items())
要向Flask添加自定义转换器,请将其添加到app.url_map.converters
dictionary:
app.url_map.converters['matrix'] = MatrixConverter
在添加依赖此转换器的任何路由之前。