diff options
Diffstat (limited to 'docs/narr/viewconfig.rst')
| -rw-r--r-- | docs/narr/viewconfig.rst | 1082 |
1 files changed, 662 insertions, 420 deletions
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 5640800a2..cd5b8feb0 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -2,38 +2,27 @@ .. _view_configuration: +.. _view_lookup: + View Configuration ================== .. index:: single: view lookup -:term:`View configuration` controls how :term:`view lookup` operates in -your application. In earlier chapters, you have been exposed to a few -simple view configuration declarations without much explanation. In this -chapter we will explore the subject in detail. - -.. _view_lookup: - -View Lookup and Invocation --------------------------- - -:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding -an invoking a :term:`view callable`. The view lookup subsystem is passed a -:term:`context` and a :term:`request` object. +:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding and +invoking a :term:`view callable`. :term:`View configuration` controls how +:term:`view lookup` operates in your application. During any given request, +view configuration information is compared against request data by the view +lookup subsystem in order to find the "best" view callable for that request. -:term:`View configuration` information stored within in the -:term:`application registry` is compared against the context and request by -the view lookup subsystem in order to find the "best" view callable for the -set of circumstances implied by the context and request. +In earlier chapters, you have been exposed to a few simple view configuration +declarations without much explanation. In this chapter we will explore the +subject in detail. -:term:`View predicate` attributes are an important part of view -configuration that enables the :term:`View lookup` subsystem to find and -invoke the appropriate view. Predicate attributes can be thought of -like "narrowers". In general, the greater number of predicate -attributes possessed by a view's configuration, the more specific the -circumstances need to be before the registered view callable will be -invoked. +.. index:: + pair: resource; mapping to view callable + pair: URL pattern; mapping to view callable Mapping a Resource or URL Pattern to a View Callable ---------------------------------------------------- @@ -41,31 +30,23 @@ Mapping a Resource or URL Pattern to a View Callable A developer makes a :term:`view callable` available for use within a :app:`Pyramid` application via :term:`view configuration`. A view configuration associates a view callable with a set of statements that -determine the set of circumstances which must be true for the view callable -to be invoked. +determine the set of circumstances which must be true for the view callable to +be invoked. A view configuration statement is made about information present in the :term:`context` resource and the :term:`request`. -View configuration is performed in one of these ways: +View configuration is performed in one of two ways: -- by running a :term:`scan` against application source code which has a +- By running a :term:`scan` against application source code which has a :class:`pyramid.view.view_config` decorator attached to a Python object as per :ref:`mapping_views_using_a_decorator_section`. -- by using the :meth:`pyramid.config.Configurator.add_view` method as per +- By using the :meth:`pyramid.config.Configurator.add_view` method as per :ref:`mapping_views_using_imperative_config_section`. -- By specifying a view within a :term:`route configuration`. View - configuration via a route configuration is performed by using the - :meth:`pyramid.config.Configurator.add_route` method, passing a ``view`` - argument specifying a view callable. This pattern of view configuration is - deprecated as of :app:`Pyramid` 1.1. - -.. note:: A package named ``pyramid_handlers`` (available from PyPI) provides - an analogue of :term:`Pylons` -style "controllers", which are a special - kind of view class which provides more automation when your application - uses :term:`URL dispatch` solely. +.. index:: + single: view configuration parameters .. _view_configuration_parameters: @@ -75,90 +56,171 @@ View Configuration Parameters All forms of view configuration accept the same general types of arguments. Many arguments supplied during view configuration are :term:`view predicate` -arguments. View predicate arguments used during view configuration are used -to narrow the set of circumstances in which :term:`view lookup` will find a +arguments. View predicate arguments used during view configuration are used to +narrow the set of circumstances in which :term:`view lookup` will find a particular view callable. -In general, the fewer number of predicates which are supplied to a -particular view configuration, the more likely it is that the associated -view callable will be invoked. The greater the number supplied, the -less likely. A view with five predicates will always be found and -evaluated before a view with two, for example. All predicates must -match for the associated view to be called. - -This does not mean however, that :app:`Pyramid` "stops looking" when it -finds a view registration with predicates that don't match. If one set -of view predicates does not match, the "next most specific" view (if -any) is consulted for predicates, and so on, until a view is found, or -no view can be matched up with the request. The first view with a set -of predicates all of which match the request environment will be -invoked. +:term:`View predicate` attributes are an important part of view configuration +that enables the :term:`view lookup` subsystem to find and invoke the +appropriate view. The greater the number of predicate attributes possessed by +a view's configuration, the more specific the circumstances need to be before +the registered view callable will be invoked. The fewer the number of +predicates which are supplied to a particular view configuration, the more +likely it is that the associated view callable will be invoked. A view with +five predicates will always be found and evaluated before a view with two, for +example. + +This does not mean however, that :app:`Pyramid` "stops looking" when it finds a +view registration with predicates that don't match. If one set of view +predicates does not match, the "next most specific" view (if any) is consulted +for predicates, and so on, until a view is found, or no view can be matched up +with the request. The first view with a set of predicates all of which match +the request environment will be invoked. If no view can be found with predicates which allow it to be matched up with the request, :app:`Pyramid` will return an error to the user's browser, representing a "not found" (404) page. See :ref:`changing_the_notfound_view` -for more information about changing the default notfound view. +for more information about changing the default :term:`Not Found View`. -Some view configuration arguments are non-predicate arguments. These tend to +Other view configuration arguments are non-predicate arguments. These tend to modify the response of the view callable or prevent the view callable from being invoked due to an authorization policy. The presence of non-predicate arguments in a view configuration does not narrow the circumstances in which the view callable will be invoked. +.. _nonpredicate_view_args: + Non-Predicate Arguments +++++++++++++++++++++++ ``permission`` The name of a :term:`permission` that the user must possess in order to - invoke the :term:`view callable`. See :ref:`view_security_section` for - more information about view security and permissions. + invoke the :term:`view callable`. See :ref:`view_security_section` for more + information about view security and permissions. - If ``permission`` is not supplied, no permission is registered for this - view (it's accessible by any caller). + If ``permission`` is not supplied, no permission is registered for this view + (it's accessible by any caller). ``attr`` The view machinery defaults to using the ``__call__`` method of the :term:`view callable` (or the function itself, if the view callable is a function) to obtain a response. 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. + 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's ``__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 ``attr`` is not supplied, ``None`` is used (implying the function itself - if the view is a function, or the ``__call__`` callable attribute if the - view is a class). + if the view is a function, or the ``__call__`` callable attribute if the view + is a class). ``renderer`` - Denotes the :term:`renderer` implementation which will be used to construct - a :term:`response` from the associated view callable's return value. (see - also :ref:`renderers_chapter`). - - 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``) naming a - :term:`renderer` implementation. If the ``renderer`` value does not - contain a dot (``.``), the specified string 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`` value - 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. - - When the renderer is a path, although a path is usually just a simple - relative pathname (e.g. ``templates/foo.pt``, implying that a template - named "foo.pt" is in the "templates" directory relative to the directory of - the current :term:`package`), a path can be absolute, starting with a slash - on UNIX or a drive letter prefix on Windows. The path can alternately be a - :term:`asset specification` in the form - ``some.dotted.package_name:relative/path``, making it possible to address - template assets which live in a separate package. + Denotes the :term:`renderer` implementation which will be used to construct a + :term:`response` from the associated view callable's return value. + + .. seealso:: See also :ref:`renderers_chapter`. + + 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``) naming a + :term:`renderer` implementation. If the ``renderer`` value does not contain + a dot (``.``), the specified string 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`` value 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. + + When the renderer is a path—although a path is usually just a simple relative + pathname (e.g., ``templates/foo.pt``, implying that a template named "foo.pt" + is in the "templates" directory relative to the directory of the current + :term:`package`)—the path can be absolute, starting with a slash on UNIX or a + drive letter prefix on Windows. The path can alternatively be a :term:`asset + specification` in the form ``some.dotted.package_name:relative/path``, making + it possible to address template assets which live in a separate package. The ``renderer`` attribute is optional. If it is not defined, the "null" renderer is assumed (no rendering is performed and the value is passed back - to the upstream :app:`Pyramid` machinery unchanged). Note that if the - view callable itself returns a :term:`response` (see :ref:`the_response`), - the specified renderer implementation is never called. + to the upstream :app:`Pyramid` machinery unchanged). Note that if the view + callable itself returns a :term:`response` (see :ref:`the_response`), the + specified renderer implementation is never called. + +``http_cache`` + When you supply an ``http_cache`` value to a view configuration, the + ``Expires`` and ``Cache-Control`` headers of a response generated by the + associated view callable are modified. The value for ``http_cache`` may be + one of the following: + + - A nonzero integer. If it's a nonzero integer, it's treated as a number of + seconds. This number of seconds will be used to compute the ``Expires`` + header and the ``Cache-Control: max-age`` parameter of responses to + requests which call this view. For example: ``http_cache=3600`` instructs + the requesting browser to 'cache this response for an hour, please'. + + - A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` + instance, it will be converted into a number of seconds, and that number of + seconds will be used to compute the ``Expires`` header and the + ``Cache-Control: max-age`` parameter of responses to requests which call + this view. For example: ``http_cache=datetime.timedelta(days=1)`` + instructs the requesting browser to 'cache this response for a day, + please'. + + - Zero (``0``). If the value is zero, the ``Cache-Control`` and ``Expires`` + headers present in all responses from this view will be composed such that + client browser cache (and any intermediate caches) are instructed to never + cache the response. + + - A two-tuple. If it's a two-tuple (e.g., ``http_cache=(1, + {'public':True})``), the first value in the tuple may be a nonzero integer + or a ``datetime.timedelta`` instance. In either case this value will be + used as the number of seconds to cache the response. The second value in + the tuple must be a dictionary. The values present in the dictionary will + be used as input to the ``Cache-Control`` response header. For example: + ``http_cache=(3600, {'public':True})`` means 'cache for an hour, and add + ``public`` to the Cache-Control header of the response'. All keys and + values supported by the ``webob.cachecontrol.CacheControl`` interface may + be added to the dictionary. Supplying ``{'public':True}`` is equivalent to + calling ``response.cache_control.public = True``. + + Providing a non-tuple value as ``http_cache`` is equivalent to calling + ``response.cache_expires(value)`` within your view's body. + + Providing a two-tuple value as ``http_cache`` is equivalent to calling + ``response.cache_expires(value[0], **value[1])`` within your view's body. + + If you wish to avoid influencing the ``Expires`` header, and instead wish to + only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with + the first element of ``None``, i.e., ``(None, {'public':True})``. + + +``require_csrf`` + + CSRF checks will affect any request method that is not defined as a "safe" + method by RFC2616. In pratice this means that GET, HEAD, OPTIONS, and TRACE + methods will pass untouched and all others methods will require CSRF. This + option is used in combination with the ``pyramid.require_default_csrf`` + setting to control which request parameters are checked for CSRF tokens. + + This feature requires a configured :term:`session factory`. + + If this option is set to ``True`` then CSRF checks will be enabled for POST + requests to this view. The required token will be whatever was specified by + the ``pyramid.require_default_csrf`` setting, or will fallback to + ``csrf_token``. + + If this option is set to a string then CSRF checks will be enabled and it + will be used as the required token regardless of the + ``pyramid.require_default_csrf`` setting. + + If this option is set to ``False`` then CSRF checks will be disabled + regardless of the ``pyramid.require_default_csrf`` setting. + + In addition, if this option is set to ``True`` or a string then CSRF origin + checking will be enabled. + + See :ref:`auto_csrf_checking` for more information. + + .. versionadded:: 1.7 ``wrapper`` The :term:`view name` of a different :term:`view configuration` which will @@ -167,52 +229,82 @@ Non-Predicate Arguments this view as the ``request.wrapped_response`` attribute of its own request. Using a wrapper makes it possible to "chain" views together to form a composite response. The response of the outermost wrapper view will be - returned to the user. The wrapper view will be found as any view is found: - see :ref:`view_lookup`. The "best" wrapper view will be found based on the - lookup ordering: "under the hood" this wrapper view is looked up via + returned to the user. The wrapper view will be found as any view is found. + See :ref:`view_lookup`. The "best" wrapper view will be found based on the + lookup ordering. "Under the hood" this wrapper view is looked up via ``pyramid.view.render_view_to_response(context, request, - 'wrapper_viewname')``. The context and request of a wrapper view is the - same context and request of the inner view. + 'wrapper_viewname')``. The context and request of a wrapper view is the same + context and request of the inner view. If ``wrapper`` is not supplied, no wrapper view is used. ``decorator`` A :term:`dotted Python name` to a function (or the function itself) which - will be used to decorate the registered :term:`view callable`. The - decorator function will be called with the view callable as a single - argument. The view callable it is passed will accept ``(context, - request)``. The decorator must return a replacement view callable which - also accepts ``(context, request)``. + will be used to decorate the registered :term:`view callable`. The decorator + function will be called with the view callable as a single argument. The + view callable it is passed will accept ``(context, request)``. The decorator + must return a replacement view callable which also accepts ``(context, + request)``. The ``decorator`` may also be an iterable of decorators, in which + case they will be applied one after the other to the view, in reverse order. + For example:: + + @view_config(..., decorator=(decorator2, decorator1)) + def myview(request): + ... + + Is similar to doing:: + + @view_config(...) + @decorator2 + @decorator1 + def myview(request): + ... + + All view callables in the decorator chain must return a response object + implementing :class:`pyramid.interfaces.IResponse` or raise an exception: + + .. code-block:: python + + def log_timer(wrapped): + def wrapper(context, request): + start = time.time() + response = wrapped(context, request) + duration = time.time() - start + response.headers['X-View-Time'] = '%.3f' % (duration,) + log.info('view took %.3f seconds', duration) + return response + return wrapper ``mapper`` A Python object or :term:`dotted Python name` which refers to a :term:`view mapper`, or ``None``. By default it is ``None``, which indicates that the view should use the default view mapper. This plug-point is useful for - Pyramid extension developers, but it's not very useful for 'civilians' who + Pyramid extension developers, but it's not very useful for "civilians" who are just developing stock Pyramid applications. Pay no attention to the man behind the curtain. Predicate Arguments +++++++++++++++++++ -These arguments modify view lookup behavior. In general, the more predicate -arguments that are supplied, the more specific, and narrower the usage of the +These arguments modify view lookup behavior. In general the more predicate +arguments that are supplied, the more specific and narrower the usage of the configured view. ``name`` - The :term:`view name` required to match this view callable. Read - :ref:`traversal_chapter` to understand the concept of a view name. + The :term:`view name` required to match this view callable. A ``name`` + argument is typically only used when your application uses :term:`traversal`. + Read :ref:`traversal_chapter` to understand the concept of a view name. If ``name`` is not supplied, the empty string is used (implying the default view). ``context`` - An object representing a Python class that the :term:`context` resource - must be an instance of *or* the :term:`interface` that the :term:`context` + An object representing a Python class of which the :term:`context` resource + must be an instance *or* the :term:`interface` that the :term:`context` resource must provide in order for this view to be found and called. This predicate is true when the :term:`context` resource is an instance of the - represented class or if the :term:`context` resource provides the - represented interface; it is otherwise false. + represented class or if the :term:`context` resource provides the represented + interface; it is otherwise false. If ``context`` is not supplied, the value ``None``, which matches any resource, is used. @@ -222,87 +314,109 @@ configured view. the named route has matched. This value must match the ``name`` of a :term:`route configuration` - declaration (see :ref:`urldispatch_chapter`) that must match before this - view will be called. Note that the ``route`` configuration referred to by + declaration (see :ref:`urldispatch_chapter`) that must match before this view + will be called. Note that the ``route`` configuration referred to by ``route_name`` will usually have a ``*traverse`` token in the value of its ``pattern``, representing a part of the path that will be used by :term:`traversal` against the result of the route's :term:`root factory`. If ``route_name`` is not supplied, the view callable will only have a chance of being invoked if no other route was matched. This is when the - request/context pair found via :term:`resource location` does not indicate - it matched any configured route. + request/context pair found via :term:`resource location` does not indicate it + matched any configured route. ``request_type`` This value should be an :term:`interface` that the :term:`request` must provide in order for this view to be found and called. - If ``request_type`` is not supplied, the value ``None`` is used, implying - any request type. + If ``request_type`` is not supplied, the value ``None`` is used, implying any + request type. *This is an advanced feature, not often used by "civilians"*. ``request_method`` - This value can be one of the strings ``GET``, ``POST``, ``PUT``, - ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``. A view - declaration with this argument ensures that the view will only be called - when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the - WSGI environment) string matches the supplied value. + This value can be either a string (such as ``"GET"``, ``"POST"``, + ``"PUT"``, ``"DELETE"``, ``"HEAD"``, or ``"OPTIONS"``) representing an HTTP + ``REQUEST_METHOD`` or a tuple containing one or more of these strings. A + view declaration with this argument ensures that the view will only be called + when the ``method`` attribute of the request (i.e., the ``REQUEST_METHOD`` of + the WSGI environment) matches a supplied value. - If ``request_method`` is not supplied, the view will be invoked regardless - of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. + .. versionchanged:: 1.4 + The use of ``"GET"`` also implies that the view will respond to ``"HEAD"``. + + If ``request_method`` is not supplied, the view will be invoked regardless of + the ``REQUEST_METHOD`` of the :term:`WSGI` environment. ``request_param`` - This value can be any string. A view declaration with this argument - ensures that the view will only be called when the :term:`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 has a ``=`` sign in it, - e.g. ``request_param="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 view to "match" the current - request. + This value can be any string or a sequence of strings. A view declaration + with this argument ensures that the view will only be called when the + :term:`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 any value supplied has an ``=`` sign in it, e.g., + ``request_param="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 view to "match" the current request. If ``request_param`` is not supplied, the view will be invoked without consideration of keys and values in the ``request.params`` dictionary. +``match_param`` + This param may be either a single string of the format "key=value" or a tuple + containing one or more of these strings. + + This argument ensures that the view will only be called when the + :term:`request` has key/value pairs in its :term:`matchdict` that equal those + supplied in the predicate. For example, ``match_param="action=edit"`` would + require the ``action`` parameter in the :term:`matchdict` match the right + hand side of the expression (``edit``) for the view to "match" the current + request. + + If the ``match_param`` is a tuple, every key/value pair must match for the + predicate to pass. + + If ``match_param`` is not supplied, the view will be invoked without + consideration of the keys and values in ``request.matchdict``. + + .. versionadded:: 1.2 + ``containment`` - This value should be a reference to a Python class or :term:`interface` - that a parent object in the context resource's :term:`lineage` must provide - in order for this view to be found and called. The resources in your - resource tree must be "location-aware" to use this feature. + This value should be a reference to a Python class or :term:`interface` that + a parent object in the context resource's :term:`lineage` must provide in + order for this view to be found and called. The resources in your resource + tree must be "location-aware" to use this feature. - If ``containment`` is not supplied, the interfaces and classes in the - lineage are not considered when deciding whether or not to invoke the view - callable. + If ``containment`` is not supplied, the interfaces and classes in the lineage + are not considered when deciding whether or not to invoke the view callable. See :ref:`location_aware` for more information about location-awareness. ``xhr`` This value should be either ``True`` or ``False``. If this value is specified and is ``True``, the :term:`WSGI` environment must possess an - ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header that has the + ``HTTP_X_REQUESTED_WITH`` header (i.e., ``X-Requested-With``) that has the value ``XMLHttpRequest`` for the associated view callable to be found and called. This is useful for detecting AJAX requests issued from jQuery, - Prototype and other Javascript libraries. + Prototype, and other Javascript libraries. - If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is - not taken into consideration when deciding whether or not to invoke the + If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is not + taken into consideration when deciding whether or not to invoke the associated view callable. ``accept`` - The value of this argument 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 ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not - taken into consideration when deciding whether or not to invoke the - associated view callable. + The value of this argument 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 ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not taken + into consideration when deciding whether or not to invoke the associated view + callable. ``header`` This value represents an HTTP header name or a header name/value pair. @@ -310,77 +424,155 @@ configured view. If ``header`` is specified, it must be a header name or a ``headername:headervalue`` pair. - If ``header`` is specified without a value (a bare header name only, - e.g. ``If-Modified-Since``), the view will only be invoked if the HTTP - header exists with any value in the request. + If ``header`` is specified without a value (a bare header name only, e.g., + ``If-Modified-Since``), the view will only be invoked if the HTTP header + exists with any value in the request. - If ``header`` is specified, and possesses a name/value pair - (e.g. ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP - header exists *and* the HTTP header matches the value requested. When the - ``headervalue`` contains a ``:`` (colon), it will be considered a - name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). - The value portion should be a regular expression. + If ``header`` is specified, and possesses a name/value pair (e.g., + ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP header + exists *and* the HTTP header matches the value requested. When the + ``headervalue`` contains a ``:`` (colon), it will be considered a name/value + pair (e.g., ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The value + portion should be a regular expression. 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 ``header`` is not specified, the composition, presence or absence of - HTTP headers is not taken into consideration when deciding whether or not - to invoke the associated view callable. + If ``header`` is not specified, the composition, presence, or absence of HTTP + headers is not taken into consideration when deciding whether or not to + invoke the associated view callable. ``path_info`` This value represents a regular expression pattern that will be tested - against the ``PATH_INFO`` WSGI environment variable to decide whether or - not to call the associated view callable. If the regex matches, this - predicate will be ``True``. + against the ``PATH_INFO`` WSGI environment variable to decide whether or not + to call the associated view callable. If the regex matches, this predicate + will be ``True``. If ``path_info`` is not specified, the WSGI ``PATH_INFO`` is not taken into consideration when deciding whether or not to invoke the associated view callable. +``check_csrf`` + If specified, this value should be one of ``None``, ``True``, ``False``, or a + string representing the "check name". If the value is ``True`` or a string, + CSRF checking will be performed. If the value is ``False`` or ``None``, CSRF + checking will not be performed. + + If the value provided is a string, that string will be used as the "check + name". If the value provided is ``True``, ``csrf_token`` will be used as the + check name. + + If CSRF checking is performed, the checked value will be the value of + ``request.POST[check_name]``. This value will be compared against the + value of ``request.session.get_csrf_token()``, and the check will pass if + these two values are the same. If the check passes, the associated view will + be permitted to execute. If the check fails, the associated view will not be + permitted to execute. + + Note that using this feature requires a :term:`session factory` to have been + configured. + + .. versionadded:: 1.4a2 + +``physical_path`` + If specified, this value should be a string or a tuple representing the + :term:`physical path` of the context found via traversal for this predicate + to match as true. For example, ``physical_path='/'``, + ``physical_path='/a/b/c'``, or ``physical_path=('', 'a', 'b', 'c')``. This + is not a path prefix match or a regex, but a whole-path match. It's useful + when you want to always potentially show a view when some object is traversed + to, but you can't be sure about what kind of object it will be, so you can't + use the ``context`` predicate. The individual path elements between slash + characters or in tuple elements should be the Unicode representation of the + name of the resource and should not be encoded in any way. + + .. versionadded:: 1.4a3 + +``effective_principals`` + If specified, this value should be a :term:`principal` identifier or a + sequence of principal identifiers. If the + :meth:`pyramid.request.Request.effective_principals` method indicates that + every principal named in the argument list is present in the current request, + this predicate will return True; otherwise it will return False. For + example: ``effective_principals=pyramid.security.Authenticated`` or + ``effective_principals=('fred', 'group:admins')``. + + .. versionadded:: 1.4a4 + ``custom_predicates`` - If ``custom_predicates`` is specified, it must be a sequence of references - to custom predicate callables. Use custom predicates when no set of - predefined predicates do 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 + If ``custom_predicates`` is specified, it must be a sequence of references to + custom predicate callables. Use custom predicates when no set of predefined + predicates do 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 view callable will be considered viable for a given request. - If ``custom_predicates`` is not specified, no custom predicates are - used. + If ``custom_predicates`` is not specified, no custom predicates are used. + +``predicates`` + Pass a key/value pair here to use a third-party predicate registered via + :meth:`pyramid.config.Configurator.add_view_predicate`. More than one + key/value pair can be used at the same time. See + :ref:`view_and_route_predicates` for more information about third-party + predicates. + + .. versionadded:: 1.4a1 + +Inverting Predicate Values +++++++++++++++++++++++++++ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +The above example will ensure that the view is called if the request method is +*not* ``POST``, at least if no other view is more specific. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + +.. versionadded:: 1.5 + .. index:: single: view_config decorator .. _mapping_views_using_a_decorator_section: -View Configuration Using the ``@view_config`` Decorator -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -For better locality of reference, you may use the -:class:`pyramid.view.view_config` decorator to associate your view functions -with URLs instead of using imperative configuration for the same purpose. +Adding View Configuration Using the ``@view_config`` Decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. warning:: - Using this feature tends to slows down application startup slightly, as - more work is performed at application startup to scan for view - declarations. + Using this feature tends to slow down application startup slightly, as more + work is performed at application startup to scan for view configuration + declarations. For maximum startup performance, use the view configuration + method described in :ref:`mapping_views_using_imperative_config_section` + instead. -Usage of the ``view_config`` decorator is a form of :term:`declarative -configuration` in decorator form. :class:`~pyramid.view.view_config` can be -used to associate :term:`view configuration` information -- as done via the -equivalent imperative code -- with a function that acts as a :app:`Pyramid` -view callable. All arguments to the -:meth:`pyramid.config.Configurator.add_view` method (save for the ``view`` -argument) are available in decorator form and mean precisely the same thing. +The :class:`~pyramid.view.view_config` decorator can be used to associate +:term:`view configuration` information with a function, method, or class that +acts as a :app:`Pyramid` view callable. -An example of the :class:`~pyramid.view.view_config` decorator might reside in -a :app:`Pyramid` application module ``views.py``: +Here's an example of the :class:`~pyramid.view.view_config` decorator that +lives within a :app:`Pyramid` application module ``views.py``: -.. ignore-next-block .. code-block:: python :linenos: @@ -388,20 +580,18 @@ a :app:`Pyramid` application module ``views.py``: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='my_view', request_method='POST', context=MyResource, - permission='read') + @view_config(route_name='ok', request_method='POST', permission='read') def my_view(request): return Response('OK') Using this decorator as above replaces the need to add this imperative configuration stanza: -.. ignore-next-block .. code-block:: python :linenos: - config.add_view('mypackage.views.my_view', name='my_view', request_method='POST', - context=MyResource, permission='read') + config.add_view('mypackage.views.my_view', route_name='ok', + request_method='POST', permission='read') All arguments to ``view_config`` may be omitted. For example: @@ -424,9 +614,8 @@ request method, request type, request param, route name, or containment. The mere existence of a ``@view_config`` decorator doesn't suffice to perform view configuration. All that the decorator does is "annotate" the function with your configuration declarations, it doesn't process them. To make -:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, -you *must* use the ``scan`` method of a -:class:`pyramid.config.Configurator`: +:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, you +*must* use the ``scan`` method of a :class:`pyramid.config.Configurator`: .. code-block:: python :linenos: @@ -435,15 +624,28 @@ you *must* use the ``scan`` method of a # pyramid.config.Configurator class config.scan() -Please see :ref:`decorations_and_code_scanning` for detailed information -about what happens when code is scanned for configuration declarations -resulting from use of decorators like :class:`~pyramid.view.view_config`. +Please see :ref:`decorations_and_code_scanning` for detailed information about +what happens when code is scanned for configuration declarations resulting from +use of decorators like :class:`~pyramid.view.view_config`. See :ref:`configuration_module` for additional API arguments to the :meth:`~pyramid.config.Configurator.scan` method. For example, the method allows you to supply a ``package`` argument to better control exactly *which* code will be scanned. +All arguments to the :class:`~pyramid.view.view_config` decorator mean +precisely the same thing as they would if they were passed as arguments to the +:meth:`pyramid.config.Configurator.add_view` method save for the ``view`` +argument. Usage of the :class:`~pyramid.view.view_config` decorator is a form +of :term:`declarative configuration`, while +:meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative +configuration`. However, they both do the same thing. + +.. index:: + single: view_config placement + +.. _view_config_placement: + ``@view_config`` Placement ++++++++++++++++++++++++++ @@ -458,32 +660,13 @@ If your view callable is a function, it may be used as a function decorator: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='edit') + @view_config(route_name='edit') def edit(request): return Response('edited!') If your view callable is a class, the decorator can also be used as a class -decorator in Python 2.6 and better (Python 2.5 and below do not support class -decorators). All the arguments to the decorator are the same when applied -against a class as when they are applied against a function. For example: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - from pyramid.view import view_config - - @view_config() - class MyView(object): - def __init__(self, request): - self.request = request - - def __call__(self): - return Response('hello') - -You can use the :class:`~pyramid.view.view_config` decorator as a simple -callable to manually decorate classes in Python 2.5 and below without the -decorator syntactic sugar, if you wish: +decorator. All the arguments to the decorator are the same when applied against +a class as when they are applied against a function. For example: .. code-block:: python :linenos: @@ -491,6 +674,7 @@ decorator syntactic sugar, if you wish: from pyramid.response import Response from pyramid.view import view_config + @view_config(route_name='hello') class MyView(object): def __init__(self, request): self.request = request @@ -498,8 +682,6 @@ decorator syntactic sugar, if you wish: def __call__(self): return Response('hello') - my_view = view_config()(MyView) - More than one :class:`~pyramid.view.view_config` decorator can be stacked on top of any number of others. Each decorator creates a separate view registration. For example: @@ -510,8 +692,8 @@ registration. For example: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='edit') - @view_config(name='change') + @view_config(route_name='edit') + @view_config(route_name='change') def edit(request): return Response('edited!') @@ -529,21 +711,21 @@ The decorator can also be used against a method of a class: def __init__(self, request): self.request = request - @view_config(name='hello') + @view_config(route_name='hello') def amethod(self): return Response('hello') When the decorator is used against a method of a class, a view is registered for the *class*, so the class constructor must accept an argument list in one -of two forms: either it must accept a single argument ``request`` or it must -accept two arguments, ``context, request``. +of two forms: either a single argument, ``request``, or two arguments, +``context, request``. The method which is decorated must return a :term:`response`. Using the decorator against a particular method of a class is equivalent to -using the ``attr`` parameter in a decorator attached to the class itself. -For example, the above registration implied by the decorator being used -against the ``amethod`` method could be spelled equivalently as the below: +using the ``attr`` parameter in a decorator attached to the class itself. For +example, the above registration implied by the decorator being used against the +``amethod`` method could be written equivalently as follows: .. code-block:: python :linenos: @@ -551,7 +733,7 @@ against the ``amethod`` method could be spelled equivalently as the below: from pyramid.response import Response from pyramid.view import view_config - @view_config(attr='amethod', name='hello') + @view_config(attr='amethod', route_name='hello') class MyView(object): def __init__(self, request): self.request = request @@ -559,18 +741,20 @@ against the ``amethod`` method could be spelled equivalently as the below: def amethod(self): return Response('hello') + .. index:: single: add_view .. _mapping_views_using_imperative_config_section: -View Registration Using :meth:`~pyramid.config.Configurator.add_view` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding View Configuration Using :meth:`~pyramid.config.Configurator.add_view` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_view` method within -:ref:`configuration_module` is used to configure a view imperatively. The -arguments to this method are very similar to the arguments that you provide -to the ``@view_config`` decorator. For example: +:ref:`configuration_module` is used to configure a view "imperatively" (without +a :class:`~pyramid.view.view_config` decorator). The arguments to this method +are very similar to the arguments that you provide to the +:class:`~pyramid.view.view_config` decorator. For example: .. code-block:: python :linenos: @@ -582,108 +766,196 @@ to the ``@view_config`` decorator. For example: # config is assumed to be an instance of the # pyramid.config.Configurator class - config.add_view(hello_world, name='hello.html') + config.add_view(hello_world, route_name='hello') + +The first argument, a :term:`view callable`, is the only required argument. It +must either be a Python object which is the view itself or a :term:`dotted +Python name` to such an object. In the above example, the ``view callable`` is +the ``hello_world`` function. -The first argument, ``view``, is required. It must either be a Python object -which is the view itself or a :term:`dotted Python name` to such an object. -All other arguments are optional. See -:meth:`pyramid.config.Configurator.add_view` for more information. +When you use only :meth:`~pyramid.config.Configurator.add_view` to add view +configurations, you don't need to issue a :term:`scan` in order for the view +configuration to take effect. .. index:: - single: resource interfaces + single: view_defaults class decorator -.. _using_resource_interfaces: +.. _view_defaults: -Using Resource Interfaces In View Configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``@view_defaults`` Class Decorator +---------------------------------- -Instead of registering your views with a ``context`` that names a Python -resource *class*, you can optionally register a view callable with a -``context`` which is an :term:`interface`. An interface can be attached -arbitrarily to any resource object. View lookup treats context interfaces -specially, and therefore the identity of a resource can be divorced from that -of the class which implements it. As a result, associating a view with an -interface can provide more flexibility for sharing a single view between two -or more different implementations of a resource type. For example, if two -resource objects of different Python class types share the same interface, -you can use the same view configuration to specify both of them as a -``context``. +.. versionadded:: 1.3 -In order to make use of interfaces in your application during view dispatch, -you must create an interface and mark up your resource classes or instances -with interface declarations that refer to this interface. +If you use a class as a view, you can use the +:class:`pyramid.view.view_defaults` class decorator on the class to provide +defaults to the view configuration information used by every ``@view_config`` +decorator that decorates a method of that class. -To attach an interface to a resource *class*, you define the interface and -use the :func:`zope.interface.implements` function to associate the interface -with the class. +For instance, if you've got a class that has methods that represent "REST +actions", all of which are mapped to the same route but different request +methods, instead of this: .. code-block:: python :linenos: - from zope.interface import Interface - from zope.interface import implements + from pyramid.view import view_config + from pyramid.response import Response - class IHello(Interface): - """ A marker interface """ + class RESTView(object): + def __init__(self, request): + self.request = request - class Hello(object): - implements(IHello) + @view_config(route_name='rest', request_method='GET') + def get(self): + return Response('get') -To attach an interface to a resource *instance*, you define the interface and -use the :func:`zope.interface.alsoProvides` function to associate the -interface with the instance. This function mutates the instance in such a -way that the interface is attached to it. + @view_config(route_name='rest', request_method='POST') + def post(self): + return Response('post') + + @view_config(route_name='rest', request_method='DELETE') + def delete(self): + return Response('delete') + +You can do this: .. code-block:: python :linenos: - from zope.interface import Interface - from zope.interface import alsoProvides + from pyramid.view import view_defaults + from pyramid.view import view_config + from pyramid.response import Response - class IHello(Interface): - """ A marker interface """ + @view_defaults(route_name='rest') + class RESTView(object): + def __init__(self, request): + self.request = request - class Hello(object): - pass + @view_config(request_method='GET') + def get(self): + return Response('get') - def make_hello(): - hello = Hello() - alsoProvides(hello, IHello) - return hello + @view_config(request_method='POST') + def post(self): + return Response('post') -Regardless of how you associate an interface, with a resource instance, or a -resource class, the resulting code to associate that interface with a view -callable is the same. Assuming the above code that defines an ``IHello`` -interface lives in the root of your application, and its module is named -"resources.py", the interface declaration below will associate the -``mypackage.views.hello_world`` view with resources that implement, or -provide, this interface. + @view_config(request_method='DELETE') + def delete(self): + return Response('delete') + +In the above example, we were able to take the ``route_name='rest'`` argument +out of the call to each individual ``@view_config`` statement because we used a +``@view_defaults`` class decorator to provide the argument as a default to each +view method it possessed. + +Arguments passed to ``@view_config`` will override any default passed to +``@view_defaults``. + +The ``view_defaults`` class decorator can also provide defaults to the +:meth:`pyramid.config.Configurator.add_view` directive when a decorated class +is passed to that directive as its ``view`` argument. For example, instead of +this: .. code-block:: python :linenos: - # config is an instance of pyramid.config.Configurator + from pyramid.response import Response + from pyramid.config import Configurator + + class RESTView(object): + def __init__(self, request): + self.request = request + + def get(self): + return Response('get') + + def post(self): + return Response('post') + + def delete(self): + return Response('delete') + + def main(global_config, **settings): + config = Configurator() + config.add_route('rest', '/rest') + config.add_view( + RESTView, route_name='rest', attr='get', request_method='GET') + config.add_view( + RESTView, route_name='rest', attr='post', request_method='POST') + config.add_view( + RESTView, route_name='rest', attr='delete', request_method='DELETE') + return config.make_wsgi_app() + +To reduce the amount of repetition in the ``config.add_view`` statements, we +can move the ``route_name='rest'`` argument to a ``@view_defaults`` class +decorator on the ``RESTView`` class: + +.. code-block:: python + :linenos: + + from pyramid.view import view_defaults + from pyramid.response import Response + from pyramid.config import Configurator + + @view_defaults(route_name='rest') + class RESTView(object): + def __init__(self, request): + self.request = request + + def get(self): + return Response('get') + + def post(self): + return Response('post') + + def delete(self): + return Response('delete') + + def main(global_config, **settings): + config = Configurator() + config.add_route('rest', '/rest') + config.add_view(RESTView, attr='get', request_method='GET') + config.add_view(RESTView, attr='post', request_method='POST') + config.add_view(RESTView, attr='delete', request_method='DELETE') + return config.make_wsgi_app() + +:class:`pyramid.view.view_defaults` accepts the same set of arguments that +:class:`pyramid.view.view_config` does, and they have the same meaning. Each +argument passed to ``view_defaults`` provides a default for the view +configurations of methods of the class it's decorating. + +Normal Python inheritance rules apply to defaults added via ``view_defaults``. +For example: + +.. code-block:: python + :linenos: - config.add_view('mypackage.views.hello_world', name='hello.html', - context='mypackage.resources.IHello') + @view_defaults(route_name='rest') + class Foo(object): + pass + + class Bar(Foo): + pass + +The ``Bar`` class above will inherit its view defaults from the arguments +passed to the ``view_defaults`` decorator of the ``Foo`` class. To prevent +this from happening, use a ``view_defaults`` decorator without any arguments on +the subclass: -Any time a resource that is determined to be the :term:`context` provides -this interface, and a view named ``hello.html`` is looked up against it as -per the URL, the ``mypackage.views.hello_world`` view callable will be -invoked. +.. code-block:: python + :linenos: -Note, in cases where a view is registered against a resource class, and a -view is also registered against an interface that the resource class -implements, an ambiguity arises. Views registered for the resource class take -precedence over any views registered for any interface the resource class -implements. Thus, if one view configuration names a ``context`` of both the -class type of a resource, and another view configuration names a ``context`` -of interface implemented by the resource's class, and both view -configurations are otherwise identical, the view registered for the context's -class will "win". + @view_defaults(route_name='rest') + class Foo(object): + pass -For more information about defining resources with interfaces for use within -view configuration, see :ref:`resources_which_implement_interfaces`. + @view_defaults() + class Bar(Foo): + pass + +The ``view_defaults`` decorator only works as a class decorator; using it +against a function or a method will produce nonsensical results. .. index:: single: view security @@ -695,25 +967,26 @@ Configuring View Security ~~~~~~~~~~~~~~~~~~~~~~~~~ If an :term:`authorization policy` is active, any :term:`permission` attached -to a :term:`view configuration` found during view lookup will be verified. -This will ensure that the currently authenticated user possesses that -permission against the :term:`context` resource before the view function is -actually called. Here's an example of specifying a permission in a view -configuration using :meth:`~pyramid.config.Configurator.add_view`: +to a :term:`view configuration` found during view lookup will be verified. This +will ensure that the currently authenticated user possesses that permission +against the :term:`context` resource before the view function is actually +called. Here's an example of specifying a permission in a view configuration +using :meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python :linenos: # config is an instance of pyramid.config.Configurator - config.add_view('myproject.views.add_entry', name='add.html', - context='myproject.resources.IBlog', permission='add') + config.add_route('add', '/add.html', factory='mypackage.Blog') + config.add_view('myproject.views.add_entry', route_name='add', + permission='add') When an :term:`authorization policy` is enabled, this view will be protected with the ``add`` permission. The view will *not be called* if the user does not possess the ``add`` permission relative to the current :term:`context`. -Instead the :term:`forbidden view` result will be returned to the client as -per :ref:`protecting_views`. +Instead the :term:`forbidden view` result will be returned to the client as per +:ref:`protecting_views`. .. index:: single: debugging not found errors @@ -721,111 +994,80 @@ per :ref:`protecting_views`. .. _debug_notfound_section: -:exc:`NotFound` Errors -~~~~~~~~~~~~~~~~~~~~~~ +:exc:`~pyramid.exceptions.NotFound` Errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It's useful to be able to debug :exc:`NotFound` error responses when they -occur unexpectedly due to an application registry misconfiguration. To debug -these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the -``debug_notfound`` configuration file setting. Details of why a view was not -found will be printed to ``stderr``, and the browser representation of the -error will include the same information. See :ref:`environment_chapter` for -more information about how, and where to set these values. +It's useful to be able to debug :exc:`~pyramid.exceptions.NotFound` error +responses when they occur unexpectedly due to an application registry +misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` +environment variable or the ``pyramid.debug_notfound`` configuration file +setting. Details of why a view was not found will be printed to ``stderr``, +and the browser representation of the error will include the same information. +See :ref:`environment_chapter` for more information about how, and where to set +these values. .. index:: - pair: matching views; printing - single: paster pviews + single: HTTP caching -.. _displaying_matching_views: +.. _influencing_http_caching: -Displaying Matching Views for a Given URL ------------------------------------------ +Influencing HTTP Caching +------------------------ -For a big application with several views, it can be hard to keep the view -configuration details in your head, even if you defined all the views -yourself. You can use the ``paster pviews`` command in a terminal window to -print a summary of matching routes and views for a given URL in your -application. The ``paster pviews`` command accepts three arguments. The -first argument to ``pviews`` is the path to your application's ``.ini`` file. -The second is the ``app`` section name inside the ``.ini`` file which points -to your application. The third is the URL to test for matching views. +.. versionadded:: 1.1 -Here is an example for a simple view configuration using :term:`traversal`: +When a non-``None`` ``http_cache`` argument is passed to a view configuration, +Pyramid will set ``Expires`` and ``Cache-Control`` response headers in the +resulting response, causing browsers to cache the response data for some time. +See ``http_cache`` in :ref:`nonpredicate_view_args` for the allowable values +and what they mean. -.. code-block:: text - :linenos: +Sometimes it's undesirable to have these headers set as the result of returning +a response from a view, even though you'd like to decorate the view with a view +configuration decorator that has ``http_cache``. Perhaps there's an +alternative branch in your view code that returns a response that should never +be cacheable, while the "normal" branch returns something that should always be +cacheable. If this is the case, set the ``prevent_auto`` attribute of the +``response.cache_control`` object to a non-``False`` value. For example, the +below view callable is configured with a ``@view_config`` decorator that +indicates any response from the view should be cached for 3600 seconds. +However, the view itself prevents caching from taking place unless there's a +``should_cache`` GET or POST variable: - $ ../bin/paster pviews development.ini tutorial /FrontPage +.. code-block:: python - URL = /FrontPage + from pyramid.view import view_config - context: <tutorial.models.Page object at 0xa12536c> - view name: + @view_config(http_cache=3600) + def view(request): + response = Response() + if 'should_cache' not in request.params: + response.cache_control.prevent_auto = True + return response - View: - ----- - tutorial.views.view_page - required permission = view +Note that the ``http_cache`` machinery will overwrite or add to caching headers +you set within the view itself, unless you use ``prevent_auto``. -The output always has the requested URL at the top and below that all the -views that matched with their view configuration details. In this example -only one view matches, so there is just a single *View* section. For each -matching view, the full code path to the associated view callable is shown, -along with any permissions and predicates that are part of that view -configuration. +You can also turn off the effect of ``http_cache`` entirely for the duration of +a Pyramid application lifetime. To do so, set the +``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the +``pyramid.prevent_http_cache`` configuration value setting to a true value. For +more information, see :ref:`preventing_http_caching`. -A more complex configuration might generate something like this: +Note that setting ``pyramid.prevent_http_cache`` will have no effect on caching +headers that your application code itself sets. It will only prevent caching +headers that would have been set by the Pyramid HTTP caching machinery invoked +as the result of the ``http_cache`` argument to view configuration. -.. code-block:: text - :linenos: +.. index:: + pair: view configuration; debugging + +.. _debugging_view_configuration: - $ ../bin/paster pviews development.ini shootout /about - - URL = /about - - context: <shootout.models.RootFactory object at 0xa56668c> - view name: about - - Route: - ------ - route name: about - route pattern: /about - route path: /about - subpath: - route predicates (request method = GET) - - View: - ----- - shootout.views.about_view - required permission = view - view predicates (request_param testing, header X/header) - - Route: - ------ - route name: about_post - route pattern: /about - route path: /about - subpath: - route predicates (request method = POST) - - View: - ----- - shootout.views.about_view_post - required permission = view - view predicates (request_param test) - - View: - ----- - shootout.views.about_view_post2 - required permission = view - view predicates (request_param test2) - -In this case, we are dealing with a :term:`URL dispatch` application. This -specific URL has two matching routes. The matching route information is -displayed first, followed by any views that are associated with that route. -As you can see from the second matching route output, a route can be -associated with more than one view. - -For a URL that doesn't match any views, ``paster pviews`` will simply print -out a *Not found* message. +Debugging View Configuration +---------------------------- +See :ref:`displaying_matching_views` for information about how to display +each of the view callables that might match for a given URL. This can be an +effective way to figure out why a particular view callable is being called +instead of the one you'd like to be called. |
