diff options
| author | Chris McDonough <chrism@plope.com> | 2010-12-19 04:46:04 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2010-12-19 04:46:04 -0500 |
| commit | 97d7195cfd6f7022b7515df180c97180855fe217 (patch) | |
| tree | 7641c3ff86527227d308654e2d4a185ad4c17700 | |
| parent | 394a30a84044b8e9f8484150fedc31f7461a6515 (diff) | |
| download | pyramid-97d7195cfd6f7022b7515df180c97180855fe217.tar.gz pyramid-97d7195cfd6f7022b7515df180c97180855fe217.tar.bz2 pyramid-97d7195cfd6f7022b7515df180c97180855fe217.zip | |
fix urldispatch chapter
| -rw-r--r-- | docs/narr/urldispatch.rst | 821 |
1 files changed, 390 insertions, 431 deletions
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index b7164ec40..fb5b97e54 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -33,9 +33,8 @@ no self-referencing tables that form a natural hierarchy, URL dispatch is easier to use than traversal, and is often a more natural fit for creating an application that manipulates "flat" data. -The presence of calls to the -:meth:`pyramid.config.Configurator.add_route` method in imperative -configuration within your application is a sign that you're using :term:`URL +The presence of calls to the :meth:`pyramid.config.Configurator.add_route` +method within your application is a sign that you're using :term:`URL dispatch`. .. note:: @@ -51,8 +50,8 @@ If route configuration is present in an application, the :app:`Pyramid` matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request` provided -to :app:`Pyramid`, a route-specific :term:`context` resource and :term:`view -name` will be generated. In this circumstance, :app:`Pyramid` will shortcut +to :app:`Pyramid`, a route-specific :term:`context` resource will be +generated. When this happens, :app:`Pyramid` will shortcut :term:`traversal`, and will invoke :term:`view lookup` using the context resource and view name generated by URL dispatch. If the matched route names a :term:`view callable` in its configuration, that view callable will be @@ -65,13 +64,13 @@ perform resource location and view lookup. Route Configuration ------------------- -:term:`Route configuration` is the act of adding a new :term:`route` -to an application. A route has a *pattern*, representing a pattern -meant to match against the ``PATH_INFO`` portion of a URL, and a -*name*, which is used by developers within a :app:`Pyramid` -application to uniquely identify a particular route when generating a -URL. It also optionally has a ``factory``, a set of :term:`route -predicate` parameters, and a set of :term:`view` parameters. +:term:`Route configuration` is the act of adding a new :term:`route` to an +application. A route has a *pattern*, representing a pattern meant to match +against the ``PATH_INFO`` portion of a URL, and a *name*, which is used by +developers within a :app:`Pyramid` application to uniquely identify a +particular route when generating a URL. It also optionally has a +``factory``, a set of :term:`route predicate` parameters, and a set of +:term:`view` parameters. .. index:: single: add_route @@ -79,9 +78,9 @@ predicate` parameters, and a set of :term:`view` parameters. Configuring a Route via The ``add_route`` Configurator Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :meth:`pyramid.config.Configurator.add_route` method -adds a single :term:`route configuration` to the :term:`application -registry`. Here's an example: +The :meth:`pyramid.config.Configurator.add_route` method adds a single +:term:`route configuration` to the :term:`application registry`. Here's an +example: .. ignore-next-block .. code-block:: python @@ -103,12 +102,11 @@ registry`. Here's an example: Route Configuration That Names a View Callable ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a route configuration declaration names a ``view`` attribute, the -value of the attribute will reference a :term:`view callable`. A view -callable, as described in :ref:`views_chapter`, is developer-supplied -code that "does stuff" as the result of a request. For more -information about how to create view callables, see -:ref:`views_chapter`. +When a route configuration declaration names a ``view`` attribute, the value +of the attribute will reference a :term:`view callable`. A view callable, as +described in :ref:`views_chapter`, is developer-supplied code that "does +stuff" as the result of a request. For more information about how to create +view callables, see :ref:`views_chapter`. Here's an example route configuration that references a view callable: @@ -135,53 +133,51 @@ rather than an actual callable: view='myproject.views.myview') When a route configuration names a ``view`` attribute, the :term:`view -callable` named as that ``view`` attribute will always be found and -invoked when the associated route pattern matches during a request. +callable` named as that ``view`` attribute will always be found and invoked +when the associated route pattern matches during a request. The purpose of making it possible to specify a view callable within a route configuration is to prevent developers from needing to deeply understand the details of :term:`resource location` and :term:`view lookup`. When a route -names a view callable, and a request enters the system which matches the -pattern of the route, the result is simple: the view callable associated with -the route is invoked with the request that caused the invocation. +names a view callable as a ``view`` argument, and a request enters the system +which matches the pattern of the route, the result is simple: the view +callable associated with the route is invoked with the request that caused +the invocation. -For most usage, you needn't understand more than this; how it works is -an implementation detail. In the interest of completeness, however, -we'll explain how it *does* work in the following section. You can -skip it if you're uninterested. +For most usage, you needn't understand more than this; how it works is an +implementation detail. In the interest of completeness, however, we'll +explain how it *does* work in the following section. You can skip it if +you're uninterested. Route View Callable Registration and Lookup Details !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! When a ``view`` attribute is attached to a route configuration, -:app:`Pyramid` ensures that a :term:`view configuration` is -registered that will always be found when the route pattern is matched -during a request. To do so: - -- A special route-specific :term:`interface` is created at startup time - for each route configuration declaration. - -- When a route configuration declaration mentions a ``view`` - attribute, a :term:`view configuration` is registered at startup - time. This view configuration uses the route-specific interface as - a :term:`request` type. - -- At runtime, when a request causes any route to match, the - :term:`request` object is decorated with the route-specific - interface. - -- The fact that the request is decorated with a route-specific - interface causes the view lookup machinery to always use the view - callable registered using that interface by the route configuration - to service requests that match the route pattern. - -In this way, we supply a shortcut to the developer. Under the hood, -the :term:`resource location` and :term:`view lookup` subsystems -provided by :app:`Pyramid` are still being utilized, but in a way -which does not require a developer to understand either of them in -detail. It also means that we can allow a developer to combine -:term:`URL dispatch` and :term:`traversal` in various exceptional -cases as documented in :ref:`hybrid_chapter`. +:app:`Pyramid` ensures that a :term:`view configuration` is registered that +will always be found when the route pattern is matched during a request. To +do so: + +- A special route-specific :term:`interface` is created at startup time for + each route configuration declaration. + +- When a route configuration declaration mentions a ``view`` attribute, a + :term:`view configuration` is registered at startup time. This view + configuration uses the route-specific interface as a :term:`request` type. + +- At runtime, when a request causes any route to match, the :term:`request` + object is decorated with the route-specific interface. + +- The fact that the request is decorated with a route-specific interface + causes the view lookup machinery to always use the view callable registered + using that interface by the route configuration to service requests that + match the route pattern. + +In this way, we supply a shortcut to the developer. Under the hood, the +:term:`resource location` and :term:`view lookup` subsystems provided by +:app:`Pyramid` are still being utilized, but in a way which does not require +a developer to understand either of them in detail. It also means that we +can allow a developer to combine :term:`URL dispatch` and :term:`traversal` +in various exceptional cases as documented in :ref:`hybrid_chapter`. .. index:: single: route path pattern syntax @@ -191,14 +187,14 @@ cases as documented in :ref:`hybrid_chapter`. Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ -The syntax of the pattern matching language used by :app:`Pyramid` -URL dispatch in the *pattern* argument is straightforward; it is close -to that of the :term:`Routes` system used by :term:`Pylons`. +The syntax of the pattern matching language used by :app:`Pyramid` URL +dispatch in the *pattern* argument is straightforward; it is close to that of +the :term:`Routes` system used by :term:`Pylons`. -The *pattern* used in route configuration may start with a slash -character. If the pattern does not start with a slash character, an -implicit slash will be prepended to it at matching time. For example, -the following patterns are equivalent: +The *pattern* used in route configuration may start with a slash character. +If the pattern does not start with a slash character, an implicit slash will +be prepended to it at matching time. For example, the following patterns are +equivalent: .. code-block:: text @@ -210,23 +206,22 @@ and: /{foo}/bar/baz -A pattern segment (an individual item between ``/`` characters in the pattern) -may either be a literal string (e.g. ``foo``) *or* it may be a replacement -marker (e.g. ``{foo}``) or a certain combination of both. A replacement marker -does not need to be preceded by a ``/`` character. +A pattern segment (an individual item between ``/`` characters in the +pattern) may either be a literal string (e.g. ``foo``) *or* it may be a +replacement marker (e.g. ``{foo}``) or a certain combination of both. A +replacement marker does not need to be preceded by a ``/`` character. -A replacement marker is in the format ``{name}``, where this -means "accept any characters up to the next non-alphanumeric character -and use this as the ``name`` matchdict value." For example, the -following pattern defines one literal segment ("foo") and two dynamic -replacement markers ("baz", and "bar"): +A replacement marker is in the format ``{name}``, where this means "accept +any characters up to the next non-alphanumeric character and use this as the +``name`` matchdict value." For example, the following pattern defines one +literal segment ("foo") and two dynamic replacement markers ("baz", and +"bar"): .. code-block:: text foo/{baz}/{bar} -The above pattern will match these URLs, generating the following -matchdicts: +The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text @@ -240,19 +235,19 @@ It will not match the following patterns however: foo/1/2/ -> No match (trailing slash) bar/abc/def -> First segment literal mismatch -The match for a segment replacement marker in a segment will be done -only up to the first non-alphanumeric character in the segment in the -pattern. So, for instance, if this route pattern was used: +The match for a segment replacement marker in a segment will be done only up +to the first non-alphanumeric character in the segment in the pattern. So, +for instance, if this route pattern was used: .. code-block:: text foo/{name}.html -The literal path ``/foo/biz.html`` will match the above route pattern, -and the match result will be ``{'name':u'biz'}``. However, the -literal path ``/foo/biz`` will not match, because it does not contain -a literal ``.html`` at the end of the segment represented by -``{name}.html`` (it only contains ``biz``, not ``biz.html``). +The literal path ``/foo/biz.html`` will match the above route pattern, and +the match result will be ``{'name':u'biz'}``. However, the literal path +``/foo/biz`` will not match, because it does not contain a literal ``.html`` +at the end of the segment represented by ``{name}.html`` (it only contains +``biz``, not ``biz.html``). To capture both segments, two replacement markers can be used: @@ -260,27 +255,26 @@ To capture both segments, two replacement markers can be used: foo/{name}.{ext} -The literal path ``/foo/biz.html`` will match the above route pattern, -and the match result will be ``{'name': 'biz', 'ext': 'html'}``. This -occurs because the replacement marker ``{name}`` has a literal part of -``.`` (period) between the other replacement marker ``{ext}``. +The literal path ``/foo/biz.html`` will match the above route pattern, and +the match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs +because the replacement marker ``{name}`` has a literal part of ``.`` +(period) between the other replacement marker ``{ext}``. -It is possible to use two replacement markers without any literal -characters between them, for instance ``/{foo}{bar}``. However, this -would be a nonsensical pattern without specifying a custom regular -expression to restrict what each marker captures. +It is possible to use two replacement markers without any literal characters +between them, for instance ``/{foo}{bar}``. However, this would be a +nonsensical pattern without specifying a custom regular expression to +restrict what each marker captures. -Segments must contain at least one character in order to match a -segment replacement marker. For example, for the URL ``/abc/``: +Segments must contain at least one character in order to match a segment +replacement marker. For example, for the URL ``/abc/``: - ``/abc/{foo}`` will not match. - ``/{foo}/`` will match. -Note that values representing path segments matched with a -``{segment}`` match will be url-unquoted and decoded from UTF-8 into -Unicode within the matchdict. So for instance, the following -pattern: +Note that values representing path segments matched with a ``{segment}`` +match will be url-unquoted and decoded from UTF-8 into Unicode within the +matchdict. So for instance, the following pattern: .. code-block:: text @@ -292,35 +286,32 @@ When matching the following URL: foo/La%20Pe%C3%B1a -The matchdict will look like so (the value is URL-decoded / UTF-8 -decoded): +The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): .. code-block:: text {'bar':u'La Pe\xf1a'} -If the pattern has a ``*`` in it, the name which follows it is -considered a "remainder match". A remainder match *must* come at the -end of the pattern. Unlike segment replacement markers, it does not -need to be preceded by a slash. For example: +If the pattern has a ``*`` in it, the name which follows it is considered a +"remainder match". A remainder match *must* come at the end of the pattern. +Unlike segment replacement markers, it does not need to be preceded by a +slash. For example: .. code-block:: text foo/{baz}/{bar}*fizzle -The above pattern will match these URLs, generating the following -matchdicts: +The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text foo/1/2/ -> {'baz':'1', 'bar':'2', 'fizzle':()} foo/abc/def/a/b/c -> {'baz':'abc', 'bar':'def', 'fizzle':('a', 'b', 'c')} -Note that when a ``*stararg`` remainder match is matched, the value -put into the matchdict is turned into a tuple of path segments -representing the remainder of the path. These path segments are -url-unquoted and decoded from UTF-8 into Unicode. For example, for -the following pattern: +Note that when a ``*stararg`` remainder match is matched, the value put into +the matchdict is turned into a tuple of path segments representing the +remainder of the path. These path segments are url-unquoted and decoded from +UTF-8 into Unicode. For example, for the following pattern: .. code-block:: text @@ -346,8 +337,7 @@ also capture the remainder of the URL, for example: foo/{baz}/{bar}{fizzle:.*} -The above pattern will match these URLs, generating the following -matchdicts: +The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text @@ -356,8 +346,8 @@ matchdicts: This occurs because the default regular expression for a marker is ``[^/]+`` which will match everything up to the first ``/``, while ``{fizzle:.*}`` will -result in a regular expression match of ``.*`` capturing the remainder into -a single value. +result in a regular expression match of ``.*`` capturing the remainder into a +single value. .. index:: single: route ordering @@ -365,18 +355,18 @@ a single value. Route Declaration Ordering ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Route configuration declarations are evaluated in a specific -order when a request enters the system. As a result, the -order of route configuration declarations is very important. +Route configuration declarations are evaluated in a specific order when a +request enters the system. As a result, the order of route configuration +declarations is very important. -The order that routes declarations are evaluated is the order in which -they are added to the application at startup time. This is unlike -:term:`traversal`, which depends on emergent behavior which happens as -a result of traversing a resource tree. +The order that routes declarations are evaluated is the order in which they +are added to the application at startup time. This is unlike +:term:`traversal`, which depends on emergent behavior which happens as a +result of traversing a resource tree. -For routes added via the :mod:`pyramid.config.Configurator.add_route` -method, the order that routes are evaluated is the order in which they are -added to the configuration imperatively. +For routes added via the :mod:`pyramid.config.Configurator.add_route` method, +the order that routes are evaluated is the order in which they are added to +the configuration imperatively. For example, route configuration statements with the following patterns might be added in the following order: @@ -388,8 +378,8 @@ be added in the following order: In such a configuration, the ``members/abc`` pattern would *never* be matched. This is because the match ordering will always match -``members/{def}`` first; the route configuration with ``members/abc`` -will never be evaluated. +``members/{def}`` first; the route configuration with ``members/abc`` will +never be evaluated. .. index:: single: route factory @@ -419,7 +409,7 @@ In this way, each route can use a different factory, making it possible to supply a different :term:`context` resource object to the view related to each particular route. -Supplying a different context resource for each route is useful when you're +Supplying a different resource factory each route is useful when you're trying to use a :app:`Pyramid` :term:`authorization policy` to provide declarative, "context sensitive" security checks; each resource can maintain a separate :term:`ACL`, as documented in @@ -433,30 +423,29 @@ Route Configuration Arguments Route configuration ``add_route`` statements may specify a large number of arguments. -Many of these arguments are :term:`route predicate` arguments. A -route predicate argument specifies that some aspect of the request -must be true for the associated route to be considered a match during -the route matching process. +Many of these arguments are :term:`route predicate` arguments. A route +predicate argument specifies that some aspect of the request must be true for +the associated route to be considered a match during the route matching +process. -Other arguments are view configuration related arguments. These only -have an effect when the route configuration names a ``view``. +Other arguments are view configuration related arguments. These only have an +effect when the route configuration names a ``view``. -Other arguments are ``name`` and ``factory``. These arguments -represent neither predicates nor view configuration information. +Other arguments are ``name`` and ``factory``. These arguments represent +neither predicates nor view configuration information. **Non-Predicate Arguments** ``name`` - The name of the route, e.g. ``myroute``. This attribute is - required. It must be unique among all defined routes in a given - application. + The name of the route, e.g. ``myroute``. This attribute is required. It + must be unique among all defined routes in a given application. ``factory`` - A Python object (often a function or a class) or a :term:`dotted - Python name` to such an object that will generate a - :app:`Pyramid` :term:`context` resource object when this route - matches. For example, ``mypackage.resources.MyFactoryClass``. If this - argument is not specified, the traversal root factory will be used. + A Python object (often a function or a class) or a :term:`dotted Python + name` to such an object that will generate a :app:`Pyramid` resource object + as the :term:`root` when this route matches. For example, + ``mypackage.resources.MyFactoryClass``. If this argument is not specified, + the traversal root factory will be used. ``traverse`` If you would like to cause the :term:`context` resource to be something @@ -477,28 +466,28 @@ represent neither predicates nor view configuration information. become the :term:`context` resource of the request. :ref:`traversal_chapter` has more information about traversal. - If the traversal path contains segment marker names which are not - present in the ``pattern`` argument, a runtime error will occur. - The ``traverse`` pattern should not contain segment markers that do - not exist in the ``pattern``. + If the traversal path contains segment marker names which are not present + in the ``pattern`` argument, a runtime error will occur. The ``traverse`` + pattern should not contain segment markers that do not exist in the + ``pattern``. - A similar combining of routing and traversal is available when a - route is matched which contains a ``*traverse`` remainder marker in - its pattern (see :ref:`using_traverse_in_a_route_pattern`). The - ``traverse`` argument allows you to associate route patterns with an - arbitrary traversal path without using a a ``*traverse`` remainder - marker; instead you can use other match information. + A similar combining of routing and traversal is available when a route is + matched which contains a ``*traverse`` remainder marker in its pattern (see + :ref:`using_traverse_in_a_route_pattern`). The ``traverse`` argument + allows you to associate route patterns with an arbitrary traversal path + without using a a ``*traverse`` remainder marker; instead you can use other + match information. - Note that the ``traverse`` argument is ignored when attached to a - route that has a ``*traverse`` remainder marker in its pattern. + Note that the ``traverse`` argument is ignored when attached to a route + that has a ``*traverse`` remainder marker in its pattern. **Predicate Arguments** ``pattern`` - The path of the route e.g. ``ideas/{idea}``. This argument is - required. See :ref:`route_path_pattern_syntax` for information - about the syntax of route paths. If the path doesn't match the - current URL, route matching continues. + The path of the route e.g. ``ideas/{idea}``. This argument is required. + See :ref:`route_path_pattern_syntax` for information about the syntax of + route paths. If the path doesn't match the current URL, route matching + continues. .. note:: In earlier releases of this framework, this argument existed as ``path``. ``path`` continues to work as an alias for @@ -507,135 +496,123 @@ represent neither predicates nor view configuration information. ``xhr`` This value should be either ``True`` or ``False``. If this value is specified and is ``True``, the :term:`request` must possess an - ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header for this - route to match. This is useful for detecting AJAX requests issued - from jQuery, Prototype and other Javascript libraries. If this - predicate returns ``False``, route matching continues. + ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header for this route + to match. This is useful for detecting AJAX requests issued from jQuery, + Prototype and other Javascript libraries. If this predicate returns + ``False``, route matching continues. ``request_method`` A string representing an HTTP method name, e.g. ``GET``, ``POST``, - ``HEAD``, ``DELETE``, ``PUT``. If this argument is not specified, - this route will match if the request has *any* request method. If - this predicate returns ``False``, route matching continues. + ``HEAD``, ``DELETE``, ``PUT``. If this argument is not specified, this + route will match if the request has *any* request method. If this + predicate returns ``False``, route matching continues. ``path_info`` - This value represents a regular expression pattern that will be - tested against the ``PATH_INFO`` WSGI environment variable. If the - regex matches, this predicate will return ``True``. If this - predicate returns ``False``, route matching continues. + This value represents a regular expression pattern that will be tested + against the ``PATH_INFO`` WSGI environment variable. If the regex matches, + this predicate will return ``True``. If this predicate returns ``False``, + route matching continues. ``request_param`` This value can be any string. A view declaration with this argument - ensures that the associated route will only match when the request - has a key in the ``request.params`` dictionary (an HTTP ``GET`` or - ``POST`` variable) that has a name which matches the supplied value. - If the value supplied as the argument has a ``=`` sign in it, - e.g. ``request_params="foo=123"``, then the key (``foo``) must both - exist in the ``request.params`` dictionary, and the value must match - the right hand side of the expression (``123``) for the route to - "match" the current request. If this predicate returns ``False``, - route matching continues. + ensures that the associated route will only match when the request has a + key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` + variable) that has a name which matches the supplied value. If the value + supplied as the argument has a ``=`` sign in it, + e.g. ``request_params="foo=123"``, then the key (``foo``) must both exist + in the ``request.params`` dictionary, and the value must match the right + hand side of the expression (``123``) for the route to "match" the current + request. If this predicate returns ``False``, route matching continues. ``header`` - This argument represents an HTTP header name or a header name/value - pair. If the argument contains a ``:`` (colon), it will be - considered a name/value pair (e.g. ``User-Agent:Mozilla/.*`` or - ``Host:localhost``). If the value contains a colon, the value - portion should be a regular expression. If the value does not - contain a colon, the entire value will be considered to be the - header name (e.g. ``If-Modified-Since``). If the value evaluates to - a header name only without a value, the header specified by the name - must be present in the request for this predicate to be true. If - the value evaluates to a header name/value pair, the header - specified by the name must be present in the request *and* the - regular expression specified as the value must match the header - value. Whether or not the value represents a header name or a - header name/value pair, the case of the header name is not - significant. If this predicate returns ``False``, route matching - continues. + This argument represents an HTTP header name or a header name/value pair. + If the argument contains a ``:`` (colon), it will be considered a + name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). If + the value contains a colon, the value portion should be a regular + expression. If the value does not contain a colon, the entire value will + be considered to be the header name (e.g. ``If-Modified-Since``). If the + value evaluates to a header name only without a value, the header specified + by the name must be present in the request for this predicate to be true. + If the value evaluates to a header name/value pair, the header specified by + the name must be present in the request *and* the regular expression + specified as the value must match the header value. Whether or not the + value represents a header name or a header name/value pair, the case of the + header name is not significant. If this predicate returns ``False``, route + matching continues. ``accept`` This value represents a match query for one or more mimetypes in the - ``Accept`` HTTP request header. If this value is specified, it must - be in one of the following forms: a mimetype match token in the form - ``text/plain``, a wildcard mimetype match token in the form - ``text/*`` or a match-all wildcard mimetype match token in the form - ``*/*``. If any of the forms matches the ``Accept`` header of the - request, this predicate will be true. If this predicate returns - ``False``, route matching continues. + ``Accept`` HTTP request header. If this value is specified, it must be in + one of the following forms: a mimetype match token in the form + ``text/plain``, a wildcard mimetype match token in the form ``text/*`` or a + match-all wildcard mimetype match token in the form ``*/*``. If any of the + forms matches the ``Accept`` header of the request, this predicate will be + true. If this predicate returns ``False``, route matching continues. ``custom_predicates`` This value should be a sequence of references to custom predicate - callables. Use custom predicates when no set of predefined - predicates does what you need. Custom predicates can be combined - with predefined predicates as necessary. Each custom predicate - callable should accept two arguments: ``context`` and ``request`` - and should return either ``True`` or ``False`` after doing arbitrary - evaluation of the context resource and/or the request. If all callables - return ``True``, the associated route will be considered viable for - a given request. If any custom predicate returns ``False``, route - matching continues. Note that the value ``context`` will always be - ``None`` when passed to a custom route predicate. + callables. Use custom predicates when no set of predefined predicates does + what you need. Custom predicates can be combined with predefined + predicates as necessary. Each custom predicate callable should accept two + arguments: ``context`` and ``request`` and should return either ``True`` or + ``False`` after doing arbitrary evaluation of the context resource and/or + the request. If all callables return ``True``, the associated route will + be considered viable for a given request. If any custom predicate returns + ``False``, route matching continues. Note that the value ``context`` will + always be ``None`` when passed to a custom route predicate. **View-Related Arguments** ``view`` - A Python object or a :term:`dotted Python name` to such an object - that will be used as a view callable when this route + A Python object or a :term:`dotted Python name` to such an object that will + be used as a view callable when this route matches. e.g. ``mypackage.views.my_view``. ``view_context`` - A class or an :term:`interface` (or a :term:`dotted Python name` to - such an object) that the :term:`context` of the view should match - for the view named by the route to be used. This argument is only - useful if the ``view`` attribute is used. If this attribute is not - specified, the default (``None``) will be used. + A class or an :term:`interface` (or a :term:`dotted Python name` to such an + object) that the :term:`context` resource should possess for the view named + by the route to be used. If this attribute is not specified, the default + (``None``) will be used. - If the ``view`` argument is not provided, this argument has - no effect. + If the ``view`` argument is not provided, this argument has no effect. This attribute can also be spelled as ``for_`` or ``view_for``. ``view_permission`` - The permission name required to invoke the view associated with this - route. e.g. ``edit``. (see :ref:`using_security_with_urldispatch` - for more information about permissions). + The permission name required to invoke the view associated with this route. + e.g. ``edit``. (see :ref:`using_security_with_urldispatch` for more + information about permissions). - If the ``view`` attribute is not provided, this argument has - no effect. + If the ``view`` attribute is not provided, this argument has no effect. This argument can also be spelled as ``permission``. ``view_renderer`` - This is either a single string term (e.g. ``json``) or a string - implying a path or :term:`asset specification` - (e.g. ``templates/views.pt``). If the renderer value is a single - term (does not contain a dot ``.``), the specified term will be used - to look up a renderer implementation, and that renderer - implementation will be used to construct a response from the view - return value. If the renderer term contains a dot (``.``), the - specified term will be treated as a path, and the filename extension - of the last element in the path will be used to look up the renderer - implementation, which will be passed the full path. The renderer - implementation will be used to construct a response from the view - return value. See :ref:`views_which_use_a_renderer` for more - information. - - If the ``view`` argument is not provided, this argument has - no effect. + This is either a single string term (e.g. ``json``) or a string implying a + path or :term:`asset specification` (e.g. ``templates/views.pt``). If the + renderer value is a single term (does not contain a dot ``.``), the + specified term will be used to look up a renderer implementation, and that + renderer implementation will be used to construct a response from the view + return value. If the renderer term contains a dot (``.``), the specified + term will be treated as a path, and the filename extension of the last + element in the path will be used to look up the renderer implementation, + which will be passed the full path. The renderer implementation will be + used to construct a response from the view return value. See + :ref:`views_which_use_a_renderer` for more information. + + If the ``view`` argument is not provided, this argument has no effect. This argument can also be spelled as ``renderer``. ``view_attr`` - The view machinery defaults to using the ``__call__`` method of the - view callable (or the function itself, if the view callable is a - function) to obtain a response dictionary. The ``attr`` value - allows you to vary the method attribute used to obtain the response. - For example, if your view was a class, and the class has a method - named ``index`` and you wanted to use this method instead of the - class' ``__call__`` method to return the response, you'd say - ``attr="index"`` in the view configuration for the view. This is - most useful when the view definition is a class. + The view machinery defaults to using the ``__call__`` method of the view + callable (or the function itself, if the view callable is a function) to + obtain a response dictionary. The ``attr`` value allows you to vary the + method attribute used to obtain the response. For example, if your view + was a class, and the class has a method named ``index`` and you wanted to + use this method instead of the class' ``__call__`` method to return the + response, you'd say ``attr="index"`` in the view configuration for the + view. This is most useful when the view definition is a class. If the ``view`` argument is not provided, this argument has no effect. @@ -651,19 +628,18 @@ Custom Route Predicates ~~~~~~~~~~~~~~~~~~~~~~~ Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`pyramid.config.Configurator.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 :term:`request` object. +:meth:`pyramid.config.Configurator.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 +:term:`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 :class:`pyramid.interfaces.IRoute` for the API of such -a route 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 +:class:`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: +``info['match']`` is useful when predicates need access to the route match. +For example: .. code-block:: python :linenos: @@ -679,17 +655,17 @@ match. For example: config.add_route('num', '/{num}', 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 +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 :meth:`pyramid.config.Configurator.add_route`. -A custom route predicate may also *modify* the ``match`` dictionary. -For instance, a predicate might do some type conversion of values: +A custom route predicate may also *modify* the ``match`` dictionary. For +instance, a predicate might do some type conversion of values: .. code-block:: python :linenos: @@ -710,10 +686,9 @@ For instance, a predicate might do some type conversion of values: config.add_route('num', '/{year}/{month}/{day}', custom_predicates=(ymd_to_int,)) -Note that a conversion predicate is still a predicate so it must -return ``True`` or ``False``; a predicate that does *only* conversion, -such as the one we demonstrate above should unconditionally return -``True``. +Note that a conversion predicate is still a predicate so it must return +``True`` or ``False``; a predicate that does *only* conversion, such as the +one we demonstrate above should unconditionally return ``True``. To avoid the try/except uncertainty, the route pattern can contain regular expressions specifying requirements for that marker. For instance: @@ -738,28 +713,27 @@ Now the try/except is no longer needed because the route will not match at all unless these markers match ``\d+`` which requires them to be valid digits for an ``int`` type conversion. -The ``match`` dictionary passed within ``info`` to each predicate -attached to a route will be the same dictionary. Therefore, when -registering a custom predicate which modifies the ``match`` dict, the -code registering the predicate should usually arrange for the -predicate to be the *last* custom predicate in the custom predicate -list. Otherwise, custom predicates which fire subsequent to the -predicate which performs the ``match`` modification will receive the -*modified* match dictionary. +The ``match`` dictionary passed within ``info`` to each predicate attached to +a route will be the same dictionary. Therefore, when registering a custom +predicate which modifies the ``match`` dict, the code registering the +predicate should usually arrange for the predicate to be the *last* custom +predicate in the custom predicate list. Otherwise, custom predicates which +fire subsequent to the predicate which performs the ``match`` modification +will receive the *modified* match dictionary. .. warning:: - It is a poor idea to rely on ordering of custom predicates to build - some conversion pipeline, where one predicate depends on the side - effect of another. For instance, it's a poor idea to register two - custom predicates, one which handles conversion of a value to an - int, the next which handles conversion of that integer to some - custom object. Just do all that in a single custom predicate. + It is a poor idea to rely on ordering of custom predicates to build a + conversion pipeline, where one predicate depends on the side effect of + another. For instance, it's a poor idea to register two custom + predicates, one which handles conversion of a value to an int, the next + which handles conversion of that integer to some custom object. Just do + all that in a single custom predicate. -The ``route`` object in the ``info`` dict is an object that has two -useful attributes: ``name`` and ``pattern``. The ``name`` attribute -is the route name. The ``pattern`` attribute is the route pattern. -An example of using the route in a set of route predicates: +The ``route`` object in the ``info`` dict is an object that has two useful +attributes: ``name`` and ``pattern``. The ``name`` attribute is the route +name. The ``pattern`` attribute is the route pattern. An example of using +the route in a set of route predicates: .. code-block:: python :linenos: @@ -773,42 +747,39 @@ An example of using the route in a set of route predicates: config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(twenty_ten,)) -The above predicate, when added to a number of route configurations -ensures that the year match argument is '2010' if and only if the -route name is 'ymd', 'ym', or 'y'. +The above predicate, when added to a number of route configurations ensures +that the year match argument is '2010' if and only if the route name is +'ymd', 'ym', or 'y'. -See also :class:`pyramid.interfaces.IRoute` for more API -documentation about a route object. +See also :class:`pyramid.interfaces.IRoute` for more API documentation about +route objects. Route Matching -------------- -The main purpose of route configuration is to match (or not match) -the ``PATH_INFO`` present in the WSGI environment provided during a -request against a URL path pattern. +The main purpose of route configuration is to match (or not match) the +``PATH_INFO`` present in the WSGI environment provided during a request +against a URL path pattern. -The way that :app:`Pyramid` does this is very simple. When a -request enters the system, for each route configuration declaration -present in the system, :app:`Pyramid` checks the ``PATH_INFO`` -against the pattern declared. +The way that :app:`Pyramid` does this is very simple. When a request enters +the system, for each route configuration declaration present in the system, +:app:`Pyramid` checks the ``PATH_INFO`` against the pattern declared. If any route matches, the route matching process stops. The :term:`request` is decorated with a special :term:`interface` which describes it as a "route -request", the :term:`context` resource is generated, and the context, the -view name, and the resulting request are handed off to :term:`view lookup`. -This process is otherwise known as :term:`resource location`. During view -lookup, if any ``view`` argument was provided within the matched route -configuration, the :term:`view callable` it points to is called. +request", the :term:`context` resource is generated, and the context and the +resulting request are handed off to :term:`view lookup`. During view lookup, +if any ``view`` argument was provided within the matched route configuration, +the :term:`view callable` it points to is called. When a route configuration is declared, it may contain :term:`route predicate` arguments. All route predicates associated with a route -declaration must be ``True`` for the route configuration to be used -for a given request. +declaration must be ``True`` for the route configuration to be used for a +given request. -If any predicate in the set of :term:`route predicate` arguments -provided to a route configuration returns ``False``, that route is -skipped and route matching continues through the ordered set of -routes. +If any predicate in the set of :term:`route predicate` arguments provided to +a route configuration returns ``False``, that route is skipped and route +matching continues through the ordered set of routes. If no route matches after all route patterns are exhausted, :app:`Pyramid` falls back to :term:`traversal` to do :term:`resource location` and @@ -822,12 +793,12 @@ falls back to :term:`traversal` to do :term:`resource location` and The Matchdict ~~~~~~~~~~~~~ -When the URL pattern associated with a particular route configuration -is matched by a request, a dictionary named ``matchdict`` is added as -an attribute of the :term:`request` object. Thus, -``request.matchdict`` will contain the values that match replacement -patterns in the ``pattern`` element. The keys in a matchdict will be -strings. The values will be Unicode objects. +When the URL pattern associated with a particular route configuration is +matched by a request, a dictionary named ``matchdict`` is added as an +attribute of the :term:`request` object. Thus, ``request.matchdict`` will +contain the values that match replacement patterns in the ``pattern`` +element. The keys in a matchdict will be strings. The values will be +Unicode objects. .. note:: @@ -842,13 +813,12 @@ strings. The values will be Unicode objects. The Matched Route ~~~~~~~~~~~~~~~~~ -When the URL pattern associated with a particular route configuration -is matched by a request, an object named ``matched_route`` is added as -an attribute of the :term:`request` object. Thus, -``request.matched_route`` will be an object implementing the -:class:`pyramid.interfaces.IRoute` interface which matched the -request. The most useful attribute of the route object is ``name``, -which is the name of the route that matched. +When the URL pattern associated with a particular route configuration is +matched by a request, an object named ``matched_route`` is added as an +attribute of the :term:`request` object. Thus, ``request.matched_route`` +will be an object implementing the :class:`pyramid.interfaces.IRoute` +interface which matched the request. The most useful attribute of the route +object is ``name``, which is the name of the route that matched. .. note:: @@ -858,41 +828,39 @@ which is the name of the route that matched. Routing Examples ---------------- -Let's check out some examples of how route configuration statements -might be commonly declared, and what will happen if they are matched -by the information present in a request. +Let's check out some examples of how route configuration statements might be +commonly declared, and what will happen if they are matched by the +information present in a request. .. _urldispatch_example1: Example 1 ~~~~~~~~~ -The simplest route declaration which configures a route match to -*directly* result in a particular view callable being invoked: +The simplest route declaration which configures a route match to *directly* +result in a particular view callable being invoked: .. code-block:: python :linenos: config.add_route('idea', 'site/{id}', view='mypackage.views.site_view') -When a route configuration with a ``view`` attribute is added to the -system, and an incoming request matches the *pattern* of the route -configuration, the :term:`view callable` named as the ``view`` -attribute of the route configuration will be invoked. +When a route configuration with a ``view`` attribute is added to the system, +and an incoming request matches the *pattern* of the route configuration, the +:term:`view callable` named as the ``view`` attribute of the route +configuration will be invoked. In the case of the above example, when the URL of a request matches ``/site/{id}``, the view callable at the Python dotted path name -``mypackage.views.site_view`` will be called with the request. In -other words, we've associated a view callable directly with a route -pattern. +``mypackage.views.site_view`` will be called with the request. In other +words, we've associated a view callable directly with a route pattern. When the ``/site/{id}`` route pattern matches during a request, the ``site_view`` view callable is invoked with that request as its sole -argument. When this route matches, a ``matchdict`` will be generated -and attached to the request as ``request.matchdict``. If the specific -URL matched is ``/site/1``, the ``matchdict`` will be a dictionary -with a single key, ``id``; the value will be the string ``'1'``, ex.: -``{'id':'1'}``. +argument. When this route matches, a ``matchdict`` will be generated and +attached to the request as ``request.matchdict``. If the specific URL +matched is ``/site/1``, the ``matchdict`` will be a dictionary with a single +key, ``id``; the value will be the string ``'1'``, ex.: ``{'id':'1'}``. The ``mypackage.views`` module referred to above might look like so: @@ -904,17 +872,16 @@ The ``mypackage.views`` module referred to above might look like so: def site_view(request): return Response(request.matchdict['id']) -The view has access to the matchdict directly via the request, and can -access variables within it that match keys present as a result of the -route pattern. +The view has access to the matchdict directly via the request, and can access +variables within it that match keys present as a result of the route pattern. See :ref:`views_chapter` for more information about views. Example 2 ~~~~~~~~~ -Below is an example of a more complicated set of route statements you -might add to your application: +Below is an example of a more complicated set of route statements you might +add to your application: .. code-block:: python :linenos: @@ -923,8 +890,8 @@ might add to your application: config.add_route('user', 'users/{user}', view='mypackage.views.user_view') config.add_route('tag', 'tags/{tags}', view='mypackage.views.tag_view') -The above configuration will allow :app:`Pyramid` to service URLs -in these forms: +The above configuration will allow :app:`Pyramid` to service URLs in these +forms: .. code-block:: text @@ -947,17 +914,17 @@ in these forms: For the specific URL ``/tags/1``, the ``matchdict`` generated and attached to the :term:`request` will consist of ``{'tag':'1'}``. -In this example we've again associated each of our routes with a -:term:`view callable` directly. In all cases, the request, which will -have a ``matchdict`` attribute detailing the information found in the -URL by the process will be passed to the view callable. +In this example we've again associated each of our routes with a :term:`view +callable` directly. In all cases, the request, which will have a +``matchdict`` attribute detailing the information found in the URL by the +process will be passed to the view callable. Example 3 ~~~~~~~~~ -The context resource object passed in to a view found as the result of URL -dispatch will, by default, be an instance of the object returned by the -:term:`root factory` configured at startup time (the ``root_factory`` +The :term:`context` resource object passed in to a view found as the result +of URL dispatch will, by default, be an instance of the object returned by +the :term:`root factory` configured at startup time (the ``root_factory`` argument to the :term:`Configurator` used to configure the application). You can override this behavior by passing in a ``factory`` argument to the @@ -992,9 +959,9 @@ representing a :term:`SQLAlchemy` model. Example 4 ~~~~~~~~~ -It is possible to create a route declaration without a ``view`` -attribute, but associate the route with a :term:`view callable` using -a ``view`` declaration. +It is possible to create a route declaration without a ``view`` attribute, +but associate the route with a :term:`view callable` using a ``view`` +declaration. .. code-block:: python :linenos: @@ -1002,21 +969,20 @@ a ``view`` declaration. config.add_route('idea', 'site/{id}') config.add_view(route_name='idea', view='mypackage.views.site_view') -This set of configuration parameters creates a configuration -completely equivalent to this example provided in -:ref:`urldispatch_example1`: +This set of configuration parameters creates a configuration completely +equivalent to this example provided in :ref:`urldispatch_example1`: .. code-block:: python :linenos: config.add_route('idea', 'site/{id}', view='mypackage.views.site_view') -In fact, the spelling which names a ``view`` attribute is just -syntactic sugar for the more verbose spelling which contains separate -view and route registrations. +In fact, the spelling which names a ``view`` attribute is just syntactic +sugar for the more verbose spelling which contains separate view and route +registrations. -More uses for this style of associating views with routes are explored -in :ref:`hybrid_chapter`. +More uses for this style of associating views with routes are explored in +:ref:`hybrid_chapter`. .. index:: single: matching the root URL @@ -1059,11 +1025,9 @@ route patterns. For example, if you've configured a route with the ``name`` from pyramid.url import route_url url = route_url('foo', request, a='1', b='2', c='3') -This would return something like the string -``http://example.com/1/2/3`` (at least if the current protocol and -hostname implied ``http:/example.com``). See the -:func:`pyramid.url.route_url` API documentation for more -information. +This would return something like the string ``http://example.com/1/2/3`` (at +least if the current protocol and hostname implied ``http:/example.com``). +See the :func:`pyramid.url.route_url` API documentation for more information. .. index:: single: redirecting to slash-appended routes @@ -1074,19 +1038,18 @@ Redirecting to Slash-Appended Routes ------------------------------------ For behavior like Django's ``APPEND_SLASH=True``, use the -:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not -Found view` in your application. Defining this view as the :term:`Not -Found view` 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``. +:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not Found +view` in your application. Defining this view as the :term:`Not Found view` +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, because this behavior is a bit magical. If the -``append_slash_notfound_view`` is configured in your application and -your route configuration looks like so: +``append_slash_notfound_view`` is configured in your application and your +route configuration looks like so: .. code-block:: python :linenos: @@ -1094,17 +1057,17 @@ your route configuration looks like so: config.add_route('noslash', 'no_slash', view='myproject.views.no_slash') config.add_route('hasslash', 'has_slash/', view='myproject.views.has_slash') -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. +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. If a request enters the application with the ``PATH_INFO`` value of ``/no_slash``, the first route will match. 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. +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. .. warning:: @@ -1123,29 +1086,27 @@ the application's startup configuration, adding the following stanza: view='pyramid.view.append_slash_notfound_view') See :ref:`view_module` and :ref:`changing_the_notfound_view` for more -information about the slash-appending not found view and for a more -general description of how to configure a not found view. +information about the slash-appending not found view and for a more general +description of how to configure a not found view. Custom Not Found View With Slash Appended Routes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There can only be one :term:`Not Found view` in any :app:`Pyramid` -application. Even if you use -:func:`pyramid.view.append_slash_notfound_view` as the Not Found -view, :app:`Pyramid` still must generate a ``404 Not Found`` -response when it cannot redirect to a slash-appended URL; this not -found response will be visible to site users. +application. Even if you use :func:`pyramid.view.append_slash_notfound_view` +as the Not Found view, :app:`Pyramid` still must generate a ``404 Not Found`` +response when it cannot redirect to a slash-appended URL; this not found +response will be visible to site users. If you don't care what this 404 response looks like, and only you need redirections to slash-appended route URLs, you may use the -:func:`pyramid.view.append_slash_notfound_view` object as the Not -Found view as described above. However, if you wish to use a *custom* -notfound view callable when a URL cannot be redirected to a -slash-appended URL, you may wish to use an instance of the -:class:`pyramid.view.AppendSlashNotFoundViewFactory` class as the -Not Found view, supplying a :term:`view callable` to be used as the -custom notfound view as the first argument to its constructor. For -instance: +:func:`pyramid.view.append_slash_notfound_view` object as the Not Found view +as described above. However, if you wish to use a *custom* notfound view +callable when a URL cannot be redirected to a slash-appended URL, you may +wish to use an instance of the +:class:`pyramid.view.AppendSlashNotFoundViewFactory` class as the Not Found +view, supplying a :term:`view callable` to be used as the custom notfound +view as the first argument to its constructor. For instance: .. code-block:: python :linenos: @@ -1159,9 +1120,9 @@ instance: custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) config.add_view(custom_append_slash, context=NotFound) -The ``notfound_view`` supplied must adhere to the two-argument view -callable calling convention of ``(context, request)`` (``context`` -will be the exception object). +The ``notfound_view`` supplied must adhere to the two-argument view callable +calling convention of ``(context, request)`` (``context`` will be the +exception object). .. _cleaning_up_after_a_request: @@ -1169,22 +1130,21 @@ Cleaning Up After a Request --------------------------- Sometimes it's required that some cleanup be performed at the end of a -request when a database connection is involved. When -:term:`traversal` is used, this cleanup is often done as a side effect -of the traversal :term:`root factory`. Often the root factory will -insert an object into the WSGI environment that performs some cleanup -when its ``__del__`` method is called. When URL dispatch is used, -however, no special root factory is required, so sometimes that option -is not open to you. - -Instead of putting this cleanup logic in the root factory, however, -you can cause a subscriber to be fired when a new request is detected; -the subscriber can do this work. - -For example, let's say you have a ``mypackage`` :app:`Pyramid` -application package that uses SQLAlchemy, and you'd like the current -SQLAlchemy database session to be removed after each request. Put the -following in the ``mypackage.run`` module: +request when a database connection is involved. When :term:`traversal` is +used, this cleanup is often done as a side effect of the traversal +:term:`root factory`. Often the root factory will insert an object into the +WSGI environment that performs some cleanup when its ``__del__`` method is +called. When URL dispatch is used, however, no special root factory is +required, so sometimes that option is not open to you. + +Instead of putting this cleanup logic in the root factory, however, you can +cause a subscriber to be fired when a new request is detected; the subscriber +can do this work. + +For example, let's say you have a ``mypackage`` :app:`Pyramid` application +package that uses SQLAlchemy, and you'd like the current SQLAlchemy database +session to be removed after each request. Put the following in the +``mypackage.__init__`` module: .. ignore-next-block .. code-block:: python @@ -1297,4 +1257,3 @@ References A tutorial showing how :term:`URL dispatch` can be used to create a :app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. - |
