URL Converter

在搜索的时候,有这样的路径:

http://filesystem.com/search/python+algorithm

这个路径要求搜索引擎搜索同时包含pythonalgorithm关键字的内容。因此后端需要处理这个路径把pythonalgorithm提取分离开来。

在Flask中常规的思路是在视图函数中把python+algorithm这一部分当做字符串然后以+为分隔split出目标字符串。

具体如下:

1
2
3
4
@app.route('/search/<string:targets>')
def search(targets):
targets = targets.split('+')
# do with targets and return response

事实上,<string:targets>string称为converter。在Flask中converter还有:

int、float、path、uuid、any。这是官方提供的标准converter。我们也可以定制自己的converter以满足上述的URL路径解析转换需求。

具体做法,只需求继承实现werkzeug.routing.BaseConverter类中的两个方法:

  • to_python: 把路径转换为Python对象

  • to_url: 把参数转换为URL形式的字符串

那么,上述要处理的URL可以用如下的代码实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import urllib.parse

from werkzeug.routing import BaseConverter
from flask import Flask

import searchservice

fs_search = searchservice.FileSystemSearcher()

app = Flask(__name__)

class SplitSearchPath(BaseConverter):
def __init__(self, url_map, separator='+'):
super().__init__(url_map)
self.separator = urllib.parse.unquote(separator)

def to_python(self, url):
return url.split(self.separator)

def to_url(self, elements):
return self.separator.join(super().to_url(e)
for e in elements)

def register_converter(app, name, converter):
app.url_map.converters[name] = converter

register_converter(app, 'list', SplitSearchPath)

@app.route('/search/<list:targets>', methods=['GET'])
def search(targets):
# targets 已经被转为list类型,不需要在这里处理字符串了
result = fs_search.search(*targets)
return result

上述定制专用的URL converter显然多了很多代码,但如果要处理复杂的URL,它的优势就突出了:把处理路径的代码从视图函数中分离处理,从而让视图函数保存清爽。

转载请包括本文地址:https://allenwind.github.io/blog/5071
更多文章请参考:https://allenwind.github.io/blog/archives/