/usr/share/doc/python-werkzeug-doc/html/_sources/routing.rst.txt is in python-werkzeug-doc 0.14.1+dfsg1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | .. _routing:
===========
URL Routing
===========
.. module:: werkzeug.routing
.. testsetup::
from werkzeug.routing import *
When it comes to combining multiple controller or view functions (however
you want to call them), you need a dispatcher. A simple way would be
applying regular expression tests on ``PATH_INFO`` and call registered
callback functions that return the value.
Werkzeug provides a much more powerful system, similar to `Routes`_. All the
objects mentioned on this page must be imported from :mod:`werkzeug.routing`, not
from :mod:`werkzeug`!
.. _Routes: http://routes.groovie.org/
Quickstart
==========
Here is a simple example which could be the URL definition for a blog::
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)]
So what does that do? First of all we create a new :class:`Map` which stores
a bunch of URL rules. Then we pass it a list of :class:`Rule` objects.
Each :class:`Rule` object is instantiated with a string that represents a rule
and an endpoint which will be the alias for what view the rule represents.
Multiple rules can have the same endpoint, but should have different arguments
to allow URL construction.
The format for the URL rules is straightforward, but explained in detail below.
Inside the WSGI application we bind the url_map to the current request which will
return a new :class:`MapAdapter`. This url_map adapter can then be used to match
or build domains for the current request.
The :meth:`MapAdapter.match` method can then either return a tuple in the form
``(endpoint, args)`` or raise one of the three exceptions
:exc:`~werkzeug.exceptions.NotFound`, :exc:`~werkzeug.exceptions.MethodNotAllowed`,
or :exc:`~werkzeug.exceptions.RequestRedirect`. For more details about those
exceptions have a look at the documentation of the :meth:`MapAdapter.match` method.
Rule Format
===========
Rule strings basically are just normal URL paths with placeholders in the
format ``<converter(arguments):name>``, where converter and the arguments
are optional. If no converter is defined, the `default` converter is used
(which means `string` in the normal configuration).
URL rules that end with a slash are branch URLs, others are leaves. If you
have `strict_slashes` enabled (which is the default), all branch URLs that are
visited without a trailing slash will trigger a redirect to the same URL with
that slash appended.
The list of converters can be extended, the default converters are explained
below.
Builtin Converters
==================
Here a list of converters that come with Werkzeug:
.. autoclass:: UnicodeConverter
.. autoclass:: PathConverter
.. autoclass:: AnyConverter
.. autoclass:: IntegerConverter
.. autoclass:: FloatConverter
.. autoclass:: UUIDConverter
Maps, Rules and Adapters
========================
.. autoclass:: Map
:members:
.. attribute:: converters
The dictionary of converters. This can be modified after the class
was created, but will only affect rules added after the
modification. If the rules are defined with the list passed to the
class, the `converters` parameter to the constructor has to be used
instead.
.. autoclass:: MapAdapter
:members:
.. autoclass:: Rule
:members: empty
Rule Factories
==============
.. autoclass:: RuleFactory
:members: get_rules
.. autoclass:: Subdomain
.. autoclass:: Submount
.. autoclass:: EndpointPrefix
Rule Templates
==============
.. autoclass:: RuleTemplate
Custom Converters
=================
You can easily add custom converters. The only thing you have to do is to
subclass :class:`BaseConverter` and pass that new converter to the url_map.
A converter has to provide two public methods: `to_python` and `to_url`,
as well as a member that represents a regular expression. Here is a small
example::
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})
If you want that converter to be the default converter, name it ``'default'``.
Host Matching
=============
.. versionadded:: 0.7
Starting with Werkzeug 0.7 it's also possible to do matching on the whole
host names instead of just the subdomain. To enable this feature you need
to pass ``host_matching=True`` to the :class:`Map` constructor and provide
the `host` argument to all routes::
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='help_index', host='help.example.com')
], host_matching=True)
Variable parts are of course also possible in the host section::
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='user_index', host='<user>.example.com')
], host_matching=True)
|