路径选择¶
当涉及到组合多个控制器或视图函数(不管您想如何调用它们)时,您需要一个调度器。一个简单的方法是在 PATH_INFO
并调用返回值的注册回调函数。
Werkzeug提供了一个更强大的系统,类似于 Routes .必须从中导入此页中提到的所有对象 werkzeug.routing
不是从 werkzeug
你说什么?
快速启动¶
下面是一个简单的示例,可以是博客的URL定义:
from werkzeug.routing import Map, Rule, NotFound, RequestRedirect
url_map = Map([
Rule('/', endpoint='blog/index'),
Rule('/<int:year>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/<int:day>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/<int:day>/<slug>',
endpoint='blog/show_post'),
Rule('/about', endpoint='blog/about_me'),
Rule('/feeds/', endpoint='blog/feeds'),
Rule('/feeds/<feed_name>.rss', endpoint='blog/show_feed')
])
def application(environ, start_response):
urls = url_map.bind_to_environ(environ)
try:
endpoint, args = urls.match()
except HTTPException, e:
return e(environ, start_response)
start_response('200 OK', [('Content-Type', 'text/plain')])
return [f'Rule points to {endpoint!r} with arguments {args!r}'.encode()]
那这是做什么的呢?首先,我们创造了一个新的 Map
它存储了一堆URL规则。然后我们给它一张 Rule
物体。
各 Rule
对象用一个表示规则的字符串和一个端点实例化,该端点将作为该规则所表示的视图的别名。多个规则可以具有相同的端点,但应具有不同的参数以允许URL构造。
URL规则的格式很简单,但在下面详细解释。
在wsgi应用程序中,我们将URL映射绑定到当前请求,该请求将返回一个新的 MapAdapter
.然后可以使用此URL映射适配器来匹配或生成当前请求的域。
这个 MapAdapter.match()
方法然后可以返回形式中的元组 (endpoint, args)
或者提出三个例外之一 NotFound
, MethodNotAllowed
或 RequestRedirect
.有关这些异常的更多详细信息,请参阅 MapAdapter.match()
方法。
规则格式¶
规则字符串是具有格式中变量部分占位符的URL路径 <converter(arguments):name>
. converter
和 arguments
(带括号)是可选的。如果没有提供转换器,则 default
使用转换器 (string
默认情况下)。下面讨论可用的转换器。
以斜线结尾的规则是“分支”,其他规则是“叶子”。如果 strict_slashes
启用(默认设置),访问不带尾随斜杠的分支URL将重定向到附加斜杠的URL。
许多HTTP服务器在接收请求时将连续的斜杠合并为一个斜杠。如果 merge_slashes
启用(默认),则在匹配和生成时,规则将在非变量部分合并斜杠。访问带有连续斜杠的URL将重定向到斜杠合并的URL。如果你想禁用 merge_slashes
对于一个 Rule
或 Map
,您还需要适当地配置web服务器。
内置转换器¶
通用类型的URL变量的转换器是内置的。可用的转换器可以被覆盖或扩展到 Map.converters
.
- class werkzeug.routing.UnicodeConverter(map, minlength=1, maxlength=None, length=None)¶
此转换器是默认转换器,只接受一个路径段以外的任何字符串。因此,字符串不能包含斜线。
这是默认的验证器。
例子::
Rule('/pages/<page>'), Rule('/<string(length=2):lang_code>')
- class werkzeug.routing.PathConverter(map, *args, **kwargs)¶
就像违约一样
UnicodeConverter
但它也匹配斜线。这对维基和类似的应用程序很有用:Rule('/<path:wikipage>') Rule('/<path:wikipage>/edit')
- class werkzeug.routing.AnyConverter(map, *items)¶
与提供的项目之一匹配。项可以是python标识符或字符串:
Rule('/<any(about, help, imprint, class, "foo,bar"):page_name>')
Changelog
在 2.2 版本发生变更: 值在构建URL时进行验证。
- class werkzeug.routing.IntegerConverter(map, fixed_digits=0, min=None, max=None, signed=False)¶
此转换器只接受整数值:
Rule("/page/<int:page>")
默认情况下,它只接受无符号的正值。这个
signed
参数将启用有符号的负值。地址:Rule("/page/<int(signed=True):page>")
- 参数:
Changelog
在 0.15 版本加入: 这个
signed
参数。
- class werkzeug.routing.FloatConverter(map, min=None, max=None, signed=False)¶
此转换器只接受浮点值:
Rule("/probability/<float:probability>")
默认情况下,它只接受无符号的正值。这个
signed
参数将启用有符号的负值。地址:Rule("/offset/<float(signed=True):offset>")
- 参数:
Changelog
在 0.15 版本加入: 这个
signed
参数。
映射、规则和适配器¶
- class werkzeug.routing.Map(rules=None, default_subdomain='', strict_slashes=True, merge_slashes=True, redirect_defaults=True, converters=None, sort_parameters=False, sort_key=None, host_matching=False)¶
map类存储所有的url规则和一些配置参数。某些配置值仅存储在 Map 实例,因为这些规则影响所有规则,其他规则只是默认值,可以为每个规则重写。注意,除了 rules 作为关键字参数!
- 参数:
rules (t.Iterable[RuleFactory] | None) -- 此映射的URL规则序列。
default_subdomain (str) -- 没有定义子域的规则的默认子域。
strict_slashes (bool) -- 如果规则以斜杠结尾,但匹配的URL没有,则重定向到带有斜杠的URL。
merge_slashes (bool) -- 在匹配或构建URL时合并连续的斜杠。匹配项将重定向到规范化的URL。不合并可变部分中的斜杠。
redirect_defaults (bool) -- 如果没有以这种方式访问,这将重定向到默认规则。这有助于创建唯一的URL。
converters (t.Mapping[str, type[BaseConverter]] | None) -- 向转换器列表中添加其他转换器的转换器的字典。如果重新定义一个转换器,这将覆盖原始转换器。
sort_parameters (bool) -- 如果设置为 True 对URL参数进行排序。参见 url_encode 了解更多详细信息。
sort_key (t.Callable[[t.Any], t.Any] | None) -- 的排序键功能 url_encode .
host_matching (bool) -- 如果设置为 True 它启用主机匹配功能并禁用子域匹配功能。如果启用 host 使用规则的参数,而不是 subdomain 一个。
在 3.0 版本发生变更: 这个
charset
和encoding_errors
参数已删除。Changelog
在 1.0 版本发生变更: 如果
url_scheme
是ws
或wss
,只有WebSocket规则匹配。在 1.0 版本发生变更: 这个
merge_slashes
参数已添加。在 0.7 版本发生变更: 这个
encoding_errors
和host_matching
添加了参数。在 0.5 版本发生变更: 这个
sort_parameters
和sort_key
添加了参数。- converters¶
转换器词典。这可以在创建类后修改,但只影响修改后添加的规则。如果规则是用传递给类的列表定义的,则 converters 必须改用构造函数的参数。
- add(rulefactory)¶
将新规则或工厂添加到映射并绑定它。要求规则未绑定到其他映射。
- 参数:
rulefactory (RuleFactory) -- 一
Rule
或RuleFactory
- 返回类型:
None
- bind(server_name, script_name=None, subdomain=None, url_scheme='http', default_method='GET', path_info=None, query_args=None)¶
返回一个新的
MapAdapter
指定给呼叫的详细信息。注意 script_name 将默认为'/'
如果没有进一步规定或 None . 这个 server_name 至少这是一个要求,因为HTTP RFC需要绝对URL来重定向,所以由Werkzeug引发的所有重定向异常都将包含完整的规范URL。如果没有路径信息传递给
match()
它将使用传递给bind的默认路径信息。虽然这对手动绑定调用没有实际意义,但是如果您将映射绑定到已经包含路径信息的wsgi环境,这将非常有用。subdomain 将默认为 default_subdomain 如果未定义此映射。如果没有 default_subdomain 不能使用子域功能。
Changelog
在 1.0 版本发生变更: 如果
url_scheme
是ws
或wss
,只有WebSocket规则匹配。在 0.15 版本发生变更:
path_info
默认为'/'
如果None
.在 0.8 版本发生变更:
query_args
可以是字符串。在 0.7 版本发生变更: 补充
query_args
.
- bind_to_environ(environ, server_name=None, subdomain=None)¶
喜欢
bind()
但是您可以将它传递给一个WSGI环境,它将从该字典中获取信息。请注意,由于协议的限制,无法获取当前子域和实域 server_name 来自环境。如果您不提供,Werkzeug将使用 SERVER_NAME 和 SERVER_PORT (或) HTTP_HOST 如有提供)如使用 server_name 具有禁用的子域功能。如果 subdomain 是 None 但是提供了一个环境和一个服务器名,它将自动计算当前子域。例子: server_name 是
'example.com'
以及 SERVER_NAME 在WSGI中 environ 是'staging.dev.example.com'
计算的子域将'staging.dev'
.如果作为environ传递的对象具有environ属性,则使用该属性的值。这允许您传递请求对象。另外 PATH_INFO 添加为默认的
MapAdapter
这样就不必将路径信息传递给match方法。Changelog
在 1.0.0 版本发生变更: 如果传递的服务器名称指定端口443,则如果传入方案为
https
没有端口。在 1.0.0 版本发生变更: 当传递的服务器名称与传入的WSGI服务器名称不匹配时,将显示警告。
在 0.8 版本发生变更: 当传递意外的服务器名称时,这将不再引发ValueError。
在 0.5 版本发生变更: 以前,这种方法接受了一个伪造的 calculate_subdomain 没有任何效果的参数。正因为如此,它被移除了。
- 参数:
- 返回类型:
- default_converters = {'any': <class 'werkzeug.routing.converters.AnyConverter'>, 'default': <class 'werkzeug.routing.converters.UnicodeConverter'>, 'float': <class 'werkzeug.routing.converters.FloatConverter'>, 'int': <class 'werkzeug.routing.converters.IntegerConverter'>, 'path': <class 'werkzeug.routing.converters.PathConverter'>, 'string': <class 'werkzeug.routing.converters.UnicodeConverter'>, 'uuid': <class 'werkzeug.routing.converters.UUIDConverter'>}¶
要使用的默认转换器的dict。
- is_endpoint_expecting(endpoint, *arguments)¶
遍历所有规则并检查端点是否需要提供参数。例如,如果某些URL需要语言代码,而其他URL不需要,并且希望稍微包装生成器,以便在未提供当前语言代码但端点需要时自动添加当前语言代码,则此功能非常有用。
- iter_rules(endpoint=None)¶
迭代所有规则或端点规则。
- lock_class()¶
更新时要使用的锁类型。
Changelog
在 1.0 版本加入.
- update()¶
在匹配和生成之前调用,以在发生更改后保持已编译规则的正确顺序。
- 返回类型:
None
- class werkzeug.routing.MapAdapter(map, server_name, script_name, subdomain, url_scheme, path_info, default_method, query_args=None)¶
返回者
Map.bind()
或Map.bind_to_environ()
并根据运行时信息进行URL匹配和构建。- 参数:
- allowed_methods(path_info=None)¶
返回与给定路径匹配的有效方法。
Changelog
在 0.7 版本加入.
- build(endpoint, values=None, method=None, force_external=False, append_unknown=True, url_scheme=None)¶
构建URL的工作方式与此相反。而不是 match 你打电话来 build 并将其传递给占位符的端点和参数听写。
这个 build 函数还接受一个名为 force_external 如果设置为 True 将强制外部URL。根据默认,只有当目标URL位于不同的子域上时,才会使用外部URL(包括服务器名称)。
>>> m = Map([ ... Rule('/', endpoint='index'), ... Rule('/downloads/', endpoint='downloads/index'), ... Rule('/downloads/<int:id>', endpoint='downloads/show') ... ]) >>> urls = m.bind("example.com", "/") >>> urls.build("index", {}) '/' >>> urls.build("downloads/show", {'id': 42}) '/downloads/42' >>> urls.build("downloads/show", {'id': 42}, force_external=True) 'http://example.com/downloads/42'
因为URL不能包含非ASCII数据,所以您将始终得到字节返回。非ASCII字符使用地图实例上定义的字符集进行urlencode。
附加值将转换为字符串,并作为URL查询字符串参数追加到URL:
>>> urls.build("index", {'q': 'My Searchstring'}) '/?q=My+Searchstring'
在处理这些附加值时,列表还被解释为多个值(根据
werkzeug.datastructures.MultiDict
):>>> urls.build("index", {'q': ['a', 'b', 'c']}) '/?q=a&q=b&q=c'
通过A
MultiDict
还将添加多个值:>>> urls.build("index", MultiDict((('p', 'z'), ('q', 'a'), ('q', 'b')))) '/?p=z&q=a&q=b'
如果生成时规则不存在 BuildError 引发异常。
build方法接受一个名为 method 如果为同一个端点指定了不同的方法,则可以指定要为其生成URL的方法。
- 参数:
endpoint (str) -- 要生成的URL的终结点。
values (Mapping[str, Any] | None) -- 要生成的URL的值。未处理的值作为查询参数附加到URL。
method (str | None) -- 如果同一端点上的不同方法有不同的URL,则为规则的HTTP方法。
force_external (bool) -- 强制执行完全规范的外部URL。如果没有提供URL方案,这将生成一个与协议相关的URL。
append_unknown (bool) -- 未知参数作为查询字符串参数附加到生成的URL中。如果希望生成器忽略这些内容,请禁用此选项。
url_scheme (str | None) -- 要用来代替边界的方案
url_scheme
。
- 返回类型:
Changelog
在 2.0 版本发生变更: 添加了
url_scheme
参数。在 0.6 版本加入: 添加了
append_unknown
参数。
- dispatch(view_func, path_info=None, method=None, catch_http_exceptions=False)¶
完成调度过程。 view_func 使用端点和具有视图值的dict调用。它应该查找view函数,调用它,并返回一个响应对象或wsgi应用程序。默认情况下不会捕获HTTP异常,这样应用程序就可以通过手动捕获来显示更好的错误消息。如果你想坚持默认的错误信息,你可以传递它。
catch_http_exceptions=True
它将捕获HTTP异常。这里有一个关于分派用法的小示例:
from werkzeug.wrappers import Request, Response from werkzeug.wsgi import responder from werkzeug.routing import Map, Rule def on_index(request): return Response('Hello from the index') url_map = Map([Rule('/', endpoint='index')]) views = {'index': on_index} @responder def application(environ, start_response): request = Request(environ) urls = url_map.bind_to_environ(environ) return urls.dispatch(lambda e, v: views[e](request, **v), catch_http_exceptions=True)
请记住,此方法也可能返回异常对象,因此请使用
Response.force_type
以获取响应对象。- 参数:
- 返回类型:
WSGIApplication
- get_host(domain_part)¶
找出给定域部分的完整主机名。域部分是一个子域,以防主机匹配被禁用或主机名已满。
- make_alias_redirect_url(path, endpoint, values, method, query_args)¶
内部调用以生成别名重定向URL。
- match(path_info: str | None = None, method: str | None = None, return_rule: Literal[False] = False, query_args: Mapping[str, Any] | str | None = None, websocket: bool | None = None) tuple[str, Mapping[str, Any]] ¶
- match(path_info: str | None = None, method: str | None = None, return_rule: Literal[True] = True, query_args: Mapping[str, Any] | str | None = None, websocket: bool | None = None) tuple[werkzeug.routing.rules.Rule, Mapping[str, Any]]
用法很简单:只需将匹配方法、当前路径信息以及方法(默认为 GET )。然后会发生以下事情:
你收到一个 NotFound 指示没有匹配的URL的异常。A NotFound 异常也是一个wsgi应用程序,您可以调用它来获取默认的“找不到页面”页面(恰好是与 werkzeug.exceptions.NotFound )
你收到一个 MethodNotAllowed 指示此URL与当前请求方法不匹配的异常。这对于RESTful应用程序很有用。
你收到一个 RequestRedirect 例外 new_url 属性。此异常用于通知来自wsgi应用程序的请求werkzeug请求。例如,如果您请求
/foo
尽管正确的URL是/foo/
你可以使用 RequestRedirect 实例作为类似于对象的响应,类似于 HTTPException .你收到一个
WebsocketMismatch
如果唯一匹配项是WebSocket规则但绑定是HTTP请求,或者匹配项是HTTP规则但绑定是WebSocket请求,则异常。你得到了一个元组
(endpoint, arguments)
如果有匹配(除非 return_rule 是真的,在这种情况下,你会得到一个元组(rule, arguments)
)
如果未将路径信息传递给match方法,则使用映射的默认路径信息(如果未显式定义,则默认为根URL)。
引发的所有异常都是 HTTPException 因此它们可以用作WSGI响应。它们都将呈现一般性错误或重定向页面。
下面是一个匹配的小示例:
>>> m = Map([ ... Rule('/', endpoint='index'), ... Rule('/downloads/', endpoint='downloads/index'), ... Rule('/downloads/<int:id>', endpoint='downloads/show') ... ]) >>> urls = m.bind("example.com", "/") >>> urls.match("/", "GET") ('index', {}) >>> urls.match("/downloads/42") ('downloads/show', {'id': 42})
以下是重定向和丢失URL时发生的情况:
>>> urls.match("/downloads") Traceback (most recent call last): ... RequestRedirect: http://example.com/downloads/ >>> urls.match("/missing") Traceback (most recent call last): ... NotFound: 404 Not Found
- 参数:
path_info -- 用于匹配的路径信息。重写绑定上指定的路径信息。
method -- 用于匹配的HTTP方法。重写绑定上指定的方法。
return_rule -- 返回匹配的规则,而不仅仅是端点(默认为 False )
query_args -- 作为字符串或字典用于自动重定向的可选查询参数。当前无法使用查询参数进行URL匹配。
websocket -- 匹配WebSocket而不是HTTP请求。websocket请求具有
ws
或wss
url_scheme
. 这会覆盖该检测。
Changelog
在 1.0 版本加入: 补充
websocket
.在 0.8 版本发生变更:
query_args
可以是字符串。在 0.7 版本加入: 补充
query_args
.在 0.6 版本加入: 补充
return_rule
.
- class werkzeug.routing.Rule(string, defaults=None, subdomain=None, methods=None, build_only=False, endpoint=None, strict_slashes=None, merge_slashes=None, redirect_to=None, alias=False, host=None, websocket=False)¶
规则表示一个URL模式。有一些选择 Rule 这改变了它的行为方式并传递给 Rule 建造师。注意,除了规则字符串之外,所有参数 must be关键字参数,以便在Werkzeug升级时不中断应用程序。
- string
规则字符串基本上只是普通的URL路径,格式中有占位符
<converter(arguments):name>
其中转换器和参数是可选的。如果没有定义转换器, default 使用转换器,这意味着 string 在正常配置中。以斜线结尾的URL规则是分支URL,其他规则是叶。如果你有 strict_slashes 启用(这是默认设置),所有匹配的没有尾随斜杠的分支URL都将触发对相同URL的重定向,并附加缺少的斜杠。
转换器定义在 Map .
- endpoint
此规则的终结点。这可以是任何东西。对函数、字符串、数字等的引用。首选方法是使用字符串,因为端点用于生成URL。
- defaults
具有相同端点的其他规则的默认值的可选dict。这有点棘手,但如果您想拥有唯一的URL,这很有用:
url_map = Map([ Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), Rule('/all/page/<int:page>', endpoint='all_entries') ])
如果用户现在访问
http://example.com/all/page/1
它们将被重定向至http://example.com/all/
。如果 redirect_defaults 在上被禁用 Map 实例这只会影响URL的生成。- subdomain
此规则的子域规则字符串。如果未指定,则规则仅与 default_subdomain 在地图上。如果映射未绑定到子域,则禁用此功能。
如果希望在不同子域上具有用户配置文件,并且所有子域都转发到应用程序,则此功能非常有用:
url_map = Map([ Rule('/', subdomain='<username>', endpoint='user/homepage'), Rule('/stats', subdomain='<username>', endpoint='user/stats') ])
- methods
此规则适用的HTTP方法序列。如果未指定,则允许使用所有方法。例如,如果您希望 POST 和 GET .如果定义了方法,并且路径匹配,但与之匹配的方法不在此列表或该路径的另一个规则列表中,则引发的错误类型为 MethodNotAllowed 而不是 NotFound . 如果 GET 出现在方法列表中,并且 HEAD 不是, HEAD 自动添加。
- strict_slashes
重写 Map 设置为 strict_slashes 仅适用于此规则。如果未指定 Map 使用设置。
- merge_slashes
重写
Map.merge_slashes
为了这个规则。- build_only
将此设置为true,则规则将永远不匹配,但将创建可生成的URL。如果您的子域或文件夹中的资源不是由wsgi应用程序处理的(如静态数据),则此功能非常有用。
- redirect_to
如果给定,则必须是字符串或可调用的。如果是可调用的,则使用触发匹配的URL适配器和作为关键字参数的URL值进行调用,并且必须返回重定向的目标,否则必须是具有规则语法中占位符的字符串:
def foo_with_slug(adapter, id): # ask the database for the slug for the old id. this of # course has nothing to do with werkzeug. return f'foo/{Foo.get_slug_for_id(id)}' url_map = Map([ Rule('/foo/<slug>', endpoint='foo'), Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'), Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug) ])
当规则匹配时,路由系统将引发 RequestRedirect 重定向的目标出现异常。
请记住,该URL将与脚本的URL根进行联接,因此不要在目标URL上使用前导斜杠,除非您真正指的是该域的根。
- alias
如果启用,此规则将用作具有相同端点和参数的另一个规则的别名。
- host
如果提供了,并且URL映射启用了主机匹配,则可以使用它为整个主机提供匹配规则。这也意味着子域功能被禁用。
- websocket
如果
True
,此规则仅与WebSocket匹配 (ws://
,wss://
)请求。默认情况下,规则只匹配HTTP请求。
Changelog
在 2.1 版本发生变更: 百分比编码的换行符 (
%0a
),由WSGI服务器解码,在路由时考虑,而不是提前终止匹配。在 1.0 版本加入: 补充
websocket
.在 1.0 版本加入: 补充
merge_slashes
.在 0.7 版本加入: 补充
alias
和host
.在 0.6.1 版本发生变更:
HEAD
被添加到methods
如果GET
是存在的。
火柴盒¶
规则工厂¶
- class werkzeug.routing.RuleFactory¶
一旦有了更复杂的URL设置,最好使用规则工厂来避免重复的任务。其中一些是内置的,其他的可以通过子类化添加。 RuleFactory 压倒一切 get_rules .
- class werkzeug.routing.Subdomain(subdomain, rules)¶
此工厂提供的所有URL都将子域设置为特定域。例如,如果您想使用当前语言的子域,这可能是一个很好的设置:
url_map = Map([ Rule('/', endpoint='#select_language'), Subdomain('<string(length=2):lang_code>', [ Rule('/', endpoint='index'), Rule('/about', endpoint='about'), Rule('/help', endpoint='help') ]) ])
所有规则,除了
'#select_language'
Endpoint现在将侦听包含当前请求的语言代码的两个字母长的子域。- 参数:
subdomain (str) --
rules (t.Iterable[RuleFactory]) --
- class werkzeug.routing.Submount(path, rules)¶
喜欢 Subdomain 但在URL规则前面加上给定的字符串:
url_map = Map([ Rule('/', endpoint='index'), Submount('/blog', [ Rule('/', endpoint='blog/index'), Rule('/entry/<entry_slug>', endpoint='blog/show') ]) ])
现在的规则
'blog/show'
比赛/blog/entry/<entry_slug>
.- 参数:
path (str) --
rules (t.Iterable[RuleFactory]) --
- class werkzeug.routing.EndpointPrefix(prefix, rules)¶
在所有端点(必须是此工厂的字符串)前面加上另一个字符串。这对子应用程序很有用:
url_map = Map([ Rule('/', endpoint='index'), EndpointPrefix('blog/', [Submount('/blog', [ Rule('/', endpoint='index'), Rule('/entry/<entry_slug>', endpoint='show') ])]) ])
- 参数:
prefix (str) --
rules (t.Iterable[RuleFactory]) --
则模板¶
- class werkzeug.routing.RuleTemplate(rules)¶
返回已包装的规则的副本,并展开端点、规则、默认值或子域部分中的字符串模板。
下面是这样一个规则模板的小示例:
from werkzeug.routing import Map, Rule, RuleTemplate resource = RuleTemplate([ Rule('/$name/', endpoint='$name.list'), Rule('/$name/<int:id>', endpoint='$name.show') ]) url_map = Map([resource(name='user'), resource(name='page')])
当调用规则模板时,关键字参数用于替换所有字符串参数中的占位符。
- 参数:
rules (t.Iterable[Rule]) --
自定义转换器¶
您可以添加自定义转换器,以添加内置转换器不提供的行为。要创建自定义转换器,子类 BaseConverter
然后把新课传给 Map
converters
参数,或将其添加到 url_map.converters
.
转换器应该有一个 regex
属性与要匹配的正则表达式进行匹配。如果转换器可以在URL规则中接受参数,则它应该在其 __init__
方法。整个正则表达式将作为一个组进行匹配,并用作转换的值。
如果自定义转换器可以匹配正斜杠, /
,它应该具有以下属性 part_isolating
设置为 False
。这将确保使用自定义转换器的规则正确匹配。
它可以实现 to_python
方法将匹配的字符串转换为其他对象。这也可以做额外的验证,但这是不可能的 regex
属性,并应引发 werkzeug.routing.ValidationError
在这种情况下。引发任何其他错误都将导致500个错误。
它可以实现 to_url
方法在生成URL时将python对象转换为字符串。此处引发的任何错误都将转换为 werkzeug.routing.BuildError
最终导致500个错误。
此示例实现 BooleanConverter
会匹配字符串的 "yes"
, "no"
和 "maybe"
,返回的随机值 "maybe"
. ::
from random import randrange
from werkzeug.routing import BaseConverter, ValidationError
class BooleanConverter(BaseConverter):
regex = r"(?:yes|no|maybe)"
def __init__(self, url_map, maybe=False):
super().__init__(url_map)
self.maybe = maybe
def to_python(self, value):
if value == "maybe":
if self.maybe:
return not randrange(2)
raise ValidationError
return value == 'yes'
def to_url(self, value):
return "yes" if value else "no"
from werkzeug.routing import Map, Rule
url_map = Map([
Rule("/vote/<bool:werkzeug_rocks>", endpoint="vote"),
Rule("/guess/<bool(maybe=True):foo>", endpoint="guess")
], converters={'bool': BooleanConverter})
如果要更改默认转换器,请为 "default"
关键。
主机匹配¶
Changelog
在 0.7 版本加入.
从werkzeug 0.7开始,还可以对整个主机名进行匹配,而不仅仅是子域。要启用此功能,您需要通过 host_matching=True
到 Map
并提供 host 所有路由的参数:
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='help_index', host='help.example.com')
], host_matching=True)
当然,主机部分也可以使用可变部件:
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='user_index', host='<user>.example.com')
], host_matching=True)
WebSockets¶
Changelog
在 1.0 版本加入.
如果A Rule
创建时使用 websocket=True
,只有在 Map
绑定到具有 url_scheme
属于 ws
或 wss
.
备注
Werkzeug除了路由之外没有其他WebSocket支持。这个功能主要用于ASGI项目。
url_map = Map([
Rule("/ws", endpoint="comm", websocket=True),
])
adapter = map.bind("example.org", "/ws", url_scheme="ws")
assert adapter.match() == ("comm", {})
如果唯一匹配的是WebSocket规则,而绑定是HTTP(或者唯一匹配的是HTTP,绑定是WebSocket),则 WebsocketMismatch
(源自 BadRequest
)引发异常。
由于WebSocket URL有不同的方案,规则总是用方案和主机构建的, force_external=True
是隐含的。
url = adapter.build("comm")
assert url == "ws://example.org/ws"
状态机匹配¶
默认匹配算法使用状态机,该状态机在请求路径的各个部分之间转换以查找匹配项。要了解其工作原理,请考虑以下规则:
/resource/<id>
首先,将该规则分解为两个 RulePart
。第一个是静态部分,其内容等于 resource
,第二个是动态的,并且需要正则表达式匹配以 [^/]+
。
然后创建具有初始状态的状态机,该初始状态表示规则的第一个 /
。此初始状态具有到下一个状态的单一静态转换,下一个状态代表规则的第二个状态 /
。该第二状态具有到包括该规则的最终状态的单个动态转换。
为了匹配路径,匹配器开始与初始状态匹配,并遵循有效的转换。显然,这是一条试验道路 /resource/2
拥有这些部件 ""
, resource
,以及 2
它们与转换匹配,因此规则将匹配。鉴于 /other/2
将不匹配,因为 other
从初始状态的一部分。
此规则的唯一转移是如果一个 RulePart
is not part-isolating i.e. it will match /
. In this case the `` RulePart`被认为是最终的,表示必须包括试验路径的所有后续部分的过渡。