URL映射¶
Bottle内置一个强大的route引擎,可以给每个浏览器请求找到正确的回调函数。 tutorial 中已经介绍了一些基础知识。接下来是一些进阶知识和route的规则。
route的语法¶
Router
类中明确区分两种类型的route: 静态route (例如 /contact
)和 动态route (例如 /hello/<name>
)。包含了 通配符 的route即是动态route,除此之外的都是静态的。
在 0.10 版更改.
包含通配符,最简单的形式就是将其放到一对<>里面(例如 <name>
)。在同一个route里面,这个变量名需要是唯一的。因为稍后会将其当作参数传给回调函数,所以这个变量名的第一个字符应该是字母。
每一个通配符匹配一个或多个字符,直到遇到 /
。类似于 [^/]+
这样一个正则表达式,确保在route包含多个通配符的时候不出现歧义。
/<action>/<item>
这个规则匹配的情况如下
路径 |
结果 |
---|---|
保存/ 123 |
|
节省/ 123 |
不匹配 |
节省/ |
不匹配 |
/ / 123 |
不匹配 |
是否可以转义冒号之类的字符 :
with a backslash \
. This will prevent to trigger the old syntax in case you need to use :
. For example: the rule `` /<action>/item:<id>``触发旧语法(见下文),但 /action/item\:<id>
按照新语法的预期工作。
你可通过过滤器来改变这一行为,稍后会介绍。
通配符过滤器¶
0.10 新版功能.
过滤器被用于定义更特殊的通配符,可在URL中"被匹配到的部分"被传递给回调函数之前,处理其内容。可通过 <name:filter>
或 <name:filer:config>
这样的语句来声明一个过滤器。"config"部分的语法由被使用的过滤器决定。
Bottle中已实现以下过滤器:
:int 匹配一个整形数,并将其转换为int
:float 同上,匹配一个浮点数
:path 匹配所有字符,包括'/'
:re[:exp] 允许在exp中写一个正则表达式
你可在route中添加自己写的过滤器。过滤器是一个有三个返回值的函数:一个正则表达式,一个callable的对象(转换URL片段为Python对象),另一个callable对象(转换Python对象为URL片段)。过滤器仅接受一个参数,就是设置字符串(译者注:例如re过滤器的exp部分)。
app = Bottle()
def list_filter(config):
''' Matches a comma separated list of numbers. '''
delimiter = config or ','
regexp = r'\d+(%s\d)*' % re.escape(delimiter)
def to_python(match):
return map(int, match.split(delimiter))
def to_url(numbers):
return delimiter.join(map(str, numbers))
return regexp, to_python, to_url
app.router.add_filter('list', list_filter)
@app.route('/follow/<ids:list>')
def follow_users(ids):
for id in ids:
...
旧语法¶
在 0.10 版更改.
在 Bottle 0.10 版本中引入了新的语法,来简单化一些常见用例,但依然兼容旧的语法。新旧语法的区别如下。
旧语法 |
新语法 |
---|---|
|
|
|
|
|
|
|
|
请尽量在新项目中避免使用旧的语法,虽然它现在还没被废弃,但终究会的。
显式的route配置¶
route修饰器也可以直接当作函数来调用。在复杂的部署中,这种方法或许更灵活,直接由你来控制“何时”及“如何”配置route。
下面是一个简单的例子
def setup_routing():
bottle.route('/', 'GET', index)
bottle.route('/edit', ['GET', 'POST'], edit)
实际上,bottle可以是任何 Bottle
类的实例
def setup_routing(app):
app.route('/new', ['GET', 'POST'], form_new)
app.route('/edit', ['GET', 'POST'], form_edit)
app = Bottle()
setup_routing(app)