首页 > 开发 > Python > 正文

让Flask的路由URL支持正则

2017-09-06 19:39:03  来源:网友分享

flask跟web.py差别挺大的,尤其是在路由管理这块。web.py把所有的路由都集中在一起,我比较喜欢这种方式。最近用flask,发现@app.route('<URL>')中URL只支持string、int、float、path 4种类型,并不支持正则。

但我觉得flask绝对没有这么低级,肯定有支持的方法,所以来向各路长老求个方子

解决方案

通过运行如下代码:

from flask import Flaskfrom pprint import pprintif __name__ == '__main__':    app = Flask(__name__)    pprint(app.url_map.converters)

可以获取Flask默认支持的转换器:

{'any': <class 'werkzeug.routing.AnyConverter'>, 'default': <class 'werkzeug.routing.UnicodeConverter'>, 'float': <class 'werkzeug.routing.FloatConverter'>, 'int': <class 'werkzeug.routing.IntegerConverter'>, 'path': <class 'werkzeug.routing.PathConverter'>, 'string': <class 'werkzeug.routing.UnicodeConverter'>}

那如何创建一个新的路由解析转化器呢?
在Flask的app.py里有个简单的例子,这个例子是创建了一个list类型的路由转换器:

from werkzeug.routing import BaseConverter                                                                class ListConverter(BaseConverter):                      def to_python(self, value):                              return value.split(',')                          def to_url(self, values):                                return ','.join(BaseConverter.to_url(value)                          for value in values)                                                              app = Flask(__name__)                                app.url_map.converters['list'] = ListConverter

那么我们可以容易创建一个正则解析器,因为之前的转换器最终也是转换成正则的,只需要将获取的值设置为regex属性就可以使用了:

from flask import Flaskfrom werkzeug.routing import BaseConverterclass RegexConverter(BaseConverter):    def __init__(self, map, *args):        self.map = map        self.regex = args[0]app = Flask(__name__)app.url_map.converters['regex'] = RegexConverter@app.route('/view/<regex("[a-zA-Z0-9]+"):uuid>/')def view(uuid):    """    url: /view/1010000000125259/    result: view uuid:1010000000125259    """    return "view uuid: %s" % (uuid)@app.route('/<regex(".*"):url>')def not_found(url):    """    url: /hello    result: not found: 'hello'    """    return "not found: '%s'" % (url)if __name__ == '__main__':    app.run()