Flask中添加自定义转换器(Converter)
Flask 提供的测试服务器对静态文件支持不佳,解析网页的路由与静态文件的路径冲突。
在生产环境中,使用 Ngnix 等服务器都支持静态文件,所以可以用生产环境的静态文件 url 代替开发环境的 url。
或者,可以为静态文件配置单独的控制器,使用 send_from_directory
等函数返回文件。
我尝试使用下面的两个路由设置,没成功。
@app.route('/static/<path:path>')
...
@app.route('/<owner>/<repo>/<path:path>')
...
解析 /static/app/index.js
文件失败,使用第二个路由(位置问题?有时间再试)。
Stackoverflow 上的一个回答给出几种解决方法,其中一种方法使用自定义的转换器(Converter)来设置路由匹配。
Converter
转换器对路由路径中参数进行限定,比如 int
表示接受 int 型的路径参数,上面的路由中的 path
也是一种转换器,接受包括斜杠 (/
) 的字符串,通常用于路由匹配表达式的最后。
Flask 的转换器 (Converter) 来自 werkzeug 库,该库还提供自定义转换器的功能。
下面我就利用自定义一个转换器来区分静态文件和非静态文件。
Converter 说明
下面是一个来自 werkzeug 库的自定义 Converter 实例。网址
from random import randrange
from werkzeug.routing import Rule, Map, BaseConverter, ValidationError
class BooleanConverter(BaseConverter):
def __init__(self, url_map, randomify=False):
super(BooleanConverter, self).__init__(url_map)
self.randomify = randomify
self.regex = '(?:yes|no|maybe)'
def to_python(self, value):
if value == 'maybe':
if self.randomify:
return not randrange(2)
raise ValidationError()
return value == 'yes'
def to_url(self, value):
return value and 'yes' or 'no'
自定义的 Converter 需要至少定义两个方法:to_python
和 to_url
。to_python
用于将 URL 中的路径转换为 Python 对象,传递给 view 函数。to_url
则由 url_for
调用,将参数转换为 URL 中合适的形式。
识别静态文件的 Converter
从上面的描述很容易能分析出,识别静态文件的 Converter 需要在 to_python
函数中判断当前路径是否属于静态文件。
而我的静态文件都放在 static 文件加下,所以只需要检查第一个参数是否为 static 即可。
我创建一个叫 none_static
的转换器,当路径属于静态文件时,匹配失败。代码如下
class NoStaticConverter(BaseConverter):
def to_python(self, value):
if value == 'static':
raise ValidationError()
return value
def to_url(self, value):
return str(value)
将上面的路由改为
@app.route('/<no_static:owner>/<repo>')
...
该条路由就不会再匹配静态文件了。