原文链接http://werkzeug.pocoo.org/docs/0.12/routing/ 当需要组合控制器和视图函数时,我们需要一个调度器来实现。一个简单的实现方式是采用正则表达式匹测试路由信息,调用回调函数并返回结果。 Werkzeug 提供了一个类似Route[1]的强大功能.下文提到的所有对象都是从 werkzeug.routing 导入而不是 werkzeug
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 ['Rule points to %r with arguments %r' % (endpoint, args)]
上面代码的主要功能:首先我们创建一个Map对象来存储URL规则(Rule),其中Rule对象是以列表的形式放到Map中的。 每个Rule对象是一个字符串实例。这个字符串由一条规则和一个endpoint组成。endpoint的本质是rule所表示的视图的别名。多条rule可以对应一个endpoint,但必须是不同的参数构成的URL语句。
在WSGI应用中我们绑定url_map 和request对象,并返回一个新的 MapAdapter对象。此url_map 适配器通常用于为request匹配域名或生成域名。 方法MapAdapter.match()返回(endpoint, args)形式的元组,或者抛出异常: NotFound, MethodNotAllowed, 或RequestRedirect。
class werkzeug.routing.Map
Map类存储所有URL 规则和一些配置参数。影响程序全局路由规则的参数只能配置在Map实例之中。而其他的参数默认可以被每个规则重写。
class werkzeug.routing.MapAdapter
MapAdapter.build()
build方法接收force_external 参数,如果将其设置为True会显示完整的外部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数据,因此其总是返回字节形式的字符串。 附带的值会转换成unicode码附加在URL后边:
>>> urls.build("index", {
'q': 'My Searchstring'})
'/?q=My+Searchstring'
在处理附加参数时,list会被解释成多值的形式:
>>> urls.build("index", {
'q': ['a', 'b', 'c']})
'/?q=a&q=b&q=c'
MapAdapter.dispatch(view_func, path_info=None, method=None, catch_http_exceptions=False)
完成分发处理功能。调用视图函数view_func,view_func的入参是endpoint 和一个字典参数。dispatch方法实现view函数查找,调用,并返回一个response对象或WSGI应用。 一个简单的dispatch 用法实例:
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)
if__name__=='__main__':
fromwerkzeug.servingimportrun_simple
run_simple('localhost',4000,application)
MapAdapter.match()
路由规则匹配方法。 匹配举例如下:
>>> 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})
URLs丢失的例子
>> 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
class werkzeug.routing.Rule
Rule代表一种URL模式。入参endpoint可以使任意对象,例如一个方法的引用,字符或者数字等等。推荐使用字符串,因为endpoint通常用于URL生成。
class werkzeug.routing.RuleFactory
在实现复杂URL配置时,可以通过继承RuleFactory来避免重复的工作
class werkzeug.routing.Subdomain(subdomain, rules)
子域名配置
In [7]: from werkzeug.routing import *
In [8]: url_map = Map([
...: Rule('/', endpoint='#select_language'),
...: Subdomain('<string(length=2):lang_code>', [
...: Rule('/', endpoint='index'),
...: Rule('/about', endpoint='about'),
...: Rule('/help', endpoint='help')
...: ])
...: ])
In [9]: url_map
Out[9]:
Map([<Rule '/' -> #select_language>,
<Rule '<lang_code>|/about' -> about>,
<Rule '<lang_code>|/help' -> help>,
<Rule '<lang_code>|/' -> index>])
class werkzeug.routing.Submount(path, rules)
与Subdomain类似,只不过URL前缀是给定的字符串
In [10]: url_map = Map([
...: Rule('/', endpoint='index'),
...: Submount('/blog', [
...: Rule('/', endpoint='blog/index'),
...: Rule('/entry/<entry_slug>', endpoint='blog/show')
...: ])
...: ])
In [11]: url_map
Out[11]:
Map([<Rule '/blog/' -> blog/index>,
<Rule '/' -> index>,
<Rule '/blog/entry/<entry_slug>' -> blog/show>])
class werkzeug.routing.EndpointPrefix(prefix, rules)
EndpointPrefix前缀是给定的字符串
In [13]: url_map = Map([
...: Rule('/', endpoint='index'),
...: EndpointPrefix('blog/', [Submount('/blog', [
...: Rule('/', endpoint='index'),
...: Rule('/entry/<entry_slug>', endpoint='show')
...: ])])
...: ])
In [14]: url_map
Out[14]:
Map([<Rule '/blog/' -> blog/index>,
<Rule '/' -> index>,
<Rule '/blog/entry/<entry_slug>' -> blog/show>])
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')])
实现Rule规则的参数化。
通过继承BaseConverter并传入新的Converters和url_map参数来实现定制的转换器。 举例:
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'
url_map = Map([
Rule('/vote/<bool:werkzeug_rocks>', endpoint='vote'),
Rule('/vote/<bool(randomify=True):foo>', endpoint='foo')
], converters={
'bool': BooleanConverter})
[1]http://routes.readthedocs.io/en/latest/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/185134.html原文链接:https://javaforall.cn