ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 02.01.2026
Просмотров: 2744
Скачиваний: 0
8. URL DISPATCH
/a/b/c/Qu%C3%A9bec/biz
You can get a similar result by passing a tuple composed of path elements:
url = request.route_path(’abc’, foo=(u’Québec’, u’biz’))
Each value in the tuple will be url-quoted and joined by slashes in this case:
/a/b/c/Qu%C3%A9bec/biz
8.7 Static Routes
Routes may be added with a static keyword argument. For example:
1
2
config = Configurator()
config.add_route(’page’, ’/page/{action}’, static=True)
Routes added with a True static keyword argument will never be considered for matching at request time. Static routes are useful for URL generation purposes only. As a result, it is usually nonsensical to provide other non-name and non-pattern arguments to add_route() when static is passed as True, as none of the other arguments will ever be employed. A single exception to this rule is use of the pregenerator argument, which is not ignored when static is True.
latex-note.png
the static argument to add_route() is new as of Pyramid 1.1.
84
8.8.REDIRECTING TO SLASH-APPENDED ROUTES
8.8Redirecting to Slash-Appended Routes
For |
behavior like Django’s APPEND_SLASH=True, use the append_slash |
argument |
to |
pyramid.config.Configurator.add_notfound_view() or the |
equivalent |
append_slash argument to the pyramid.view.notfound_view_config decorator.
Adding append_slash=True is a way to automatically redirect requests where the URL lacks a trailing slash, but requires one to match the proper route. When configured, along with at least one other route in your application, this view will be invoked if the value of PATH_INFO does not already end in a slash, and if the value of PATH_INFO plus a slash matches any route’s pattern. In this case it does an HTTP redirect to the slash-appended PATH_INFO.
Let’s use an example. If the following routes are configured in your application:
1 |
from pyramid.httpexceptions import HTTPNotFound |
2 |
|
3 |
def notfound(request): |
4 |
return HTTPNotFound(’Not found, bro.’) |
5 |
|
6 |
def no_slash(request): |
7 |
return Response(’No slash’) |
8 |
|
9 |
def has_slash(request): |
10 |
return Response(’Has slash’) |
11
12def main(g, **settings):
13config = Configurator()
14config.add_route(’noslash’, ’no_slash’)
15config.add_route(’hasslash’, ’has_slash/’)
16config.add_view(no_slash, route_name=’noslash’)
17config.add_view(has_slash, route_name=’hasslash’)
18config.add_notfound_view(notfound, append_slash=True)
If a request enters the application with the PATH_INFO value of /no_slash, the first route will match and the browser will show “No slash”. However, if a request enters the application with the PATH_INFO value of /no_slash/, no route will match, and the slash-appending not found view will not find a matching route with an appended slash. As a result, the notfound view will be called and it will return a “Not found, bro.” body.
If a request enters the application with the PATH_INFO value of /has_slash/, the second route will match. If a request enters the application with the PATH_INFO value of /has_slash, a route will be found by the slash-appending not found view. An HTTP redirect to /has_slash/ will be returned to the user’s browser. As a result, the notfound view will never actually be called.
The following application uses the pyramid.view.notfound_view_config and pyramid.view.view_config decorators and a scan to do exactly the same job:
85
8. URL DISPATCH
1 from pyramid.httpexceptions import HTTPNotFound
2 from pyramid.view import notfound_view_config, view_config
3
4 @notfound_view_config(append_slash=True)
5 def notfound(request):
6return HTTPNotFound(’Not found, bro.’)
7
8 @view_config(route_name=’noslash’) 9 def no_slash(request):
10 return Response(’No slash’)
11
12@view_config(route_name=’hasslash’)
13def has_slash(request):
14return Response(’Has slash’)
15
16def main(g, **settings):
17config = Configurator()
18config.add_route(’noslash’, ’no_slash’)
19config.add_route(’hasslash’, ’has_slash/’)
20config.scan()
latex-warning.png
You should not rely on this mechanism to redirect POST requests. The redirect of the slash-appending not found view will turn a POST request into a GET, losing any POST data in the original request.
See pyramid.view and Changing the Not Found View for for a more general description of how to configure a view and/or a not found view.
8.9 Debugging Route Matching
It’s useful to be able to take a peek under the hood when requests that enter your application arent matching your routes as you expect them to. To debug route matching, use the
PYRAMID_DEBUG_ROUTEMATCH environment variable or the pyramid.debug_routematch configuration file setting (set either to true). Details of the route matching decision for a particular request to the Pyramid application will be printed to the stderr of the console which you started the application from. For example:
86
8.10. USING A ROUTE PREFIX TO COMPOSE APPLICATIONS
1[chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \
2 |
bin/pserve development.ini |
3Starting server in PID 13586.
4 serving on 0.0.0.0:6543 view at http://127.0.0.1:6543
52010-12-16 14:45:19,956 no route matched for url \
6 |
http://localhost:6543/wontmatch |
72010-12-16 14:45:20,010 no route matched for url \
8 |
http://localhost:6543/favicon.ico |
92010-12-16 14:41:52,084 route matched for url \
10 |
http://localhost:6543/static/logo.png; \ |
11 |
route_name: ’static/’, .... |
See Environment Variables and .ini File Settings for more information about how, and where to set these values.
You can also use the proutes command to see a display of all the routes configured in your application; for more information, see Displaying All Application Routes.
8.10 Using a Route Prefix to Compose Applications
latex-note.png
This feature is new as of Pyramid 1.2.
The pyramid.config.Configurator.include() method allows configuration statements to be included from separate files. See Rules for Building An Extensible Application for information about this method. Using pyramid.config.Configurator.include() allows you to build your application from small and potentially reusable components.
The pyramid.config.Configurator.include() method accepts an argument named route_prefix which can be useful to authors of URL-dispatch-based applications. If route_prefix is supplied to the include method, it must be a string. This string represents a route prefix that will be prepended to all route patterns added by the included configuration. Any calls to pyramid.config.Configurator.add_route() within the included callable will have their pattern prefixed with the value of route_prefix. This can be used to help mount a set of routes at a different location than the included callable’s author intended while still maintaining the same route names. For example:
87
8. URL DISPATCH
1 from pyramid.config import Configurator
2
3 def users_include(config):
4config.add_route(’show_users’, ’/show’)
5
6 def main(global_config, **settings):
7config = Configurator()
8config.include(users_include, route_prefix=’/users’)
In the above configuration, the show_users route will have |
an effective route pattern of |
|
/users/show, |
instead of /show because the route_prefix argument will be prepended |
|
to the pattern. |
The route will then only match if the URL |
path is /users/show, and |
when the pyramid.request.Request.route_url() function is called with the route name show_users, it will generate a URL with that same path.
Route prefixes are recursive, so if a callable executed via an include itself turns around and includes another callable, the second-level route prefix will be prepended with the first:
1 from pyramid.config import Configurator
2
3 def timing_include(config):
4config.add_route(’show_times’, /times’)
5
6 def users_include(config):
7config.add_route(’show_users’, ’/show’)
8config.include(timing_include, route_prefix=’/timing’)
9
10def main(global_config, **settings):
11config = Configurator()
12config.include(users_include, route_prefix=’/users’)
In the above configuration, the show_users route will still have an effective route pattern of /users/show. The show_times route however, will have an effective pattern of
/users/timing/show_times.
Route prefixes have no impact on the requirement that the set of route names in any given Pyramid configuration must be entirely unique. If you compose your URL dispatch application out of many small subapplications using pyramid.config.Configurator.include(), it’s wise to use a dotted name for your route names, so they’ll be unlikely to conflict with other packages that may be added in the future. For example:
88
8.11. CUSTOM ROUTE PREDICATES
1 from pyramid.config import Configurator
2
3 def timing_include(config):
4config.add_route(’timing.show_times’, /times’)
5
6 def users_include(config):
7config.add_route(’users.show_users’, ’/show’)
8config.include(timing_include, route_prefix=’/timing’)
9
10def main(global_config, **settings):
11config = Configurator()
12config.include(users_include, route_prefix=’/users’)
8.11 Custom Route Predicates
Each of the predicate callables fed to the custom_predicates argument of add_route() must be a callable accepting two arguments. The first argument passed to a custom predicate is a dictionary conventionally named info. The second argument is the current request object.
The info dictionary has a number of contained values: match is a dictionary: it represents the arguments matched in the URL by the route. route is an object representing the route which was matched (see pyramid.interfaces.IRoute for the API of such a route object).
info[’match’] is useful when predicates need access to the route match. For example:
1 def any_of(segment_name, *allowed):
2def predicate(info, request):
3if info[’match’][segment_name] in allowed:
4 |
return True |
5return predicate
6 |
|
7 |
num_one_two_or_three = any_of(’num’, ’one’, ’two’, ’three’) |
8 |
|
9 |
config.add_route(’route_to_num’, ’/{num}’, |
10 |
custom_predicates=(num_one_two_or_three,)) |
The above any_of function generates a predicate which ensures that the match value named segment_name is in the set of allowable values represented by allowed. We use this any_of function to generate a predicate function named num_one_two_or_three, which ensures that the num segment is one of the values one, two, or three , and use the result as a custom predicate by feeding it inside a tuple to the custom_predicates argument to add_route().
89