diff options
Diffstat (limited to 'docs/narr/views.rst')
| -rw-r--r-- | docs/narr/views.rst | 407 |
1 files changed, 218 insertions, 189 deletions
diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 04d90fda8..d30fcdae5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -18,7 +18,7 @@ a request made to your application. that implements a view *callable*, and the process of view *lookup*. -The chapter named :ref:`contextfinding_chapter` describes how, using +The chapter :ref:`contextfinding_chapter` describes how, using information from the :term:`request`, a :term:`context` and a :term:`view name` are computed. But neither the context nor the view name found are very useful unless those elements can eventually be @@ -47,15 +47,13 @@ represents a :app:`Pyramid` :term:`Request` object. A request object encapsulates a WSGI environment as represented to :app:`Pyramid` by the upstream :term:`WSGI` server. -A view callable may always return a :mod:`Pyramid` :term:`Response` object -directly. It may optionally return another arbitrary non-Response value: if a -view callable returns a non-Response result, the result must be converted into -a response by the :term:`renderer` associated with the :term:`view +A view callable can return a :mod:`Pyramid` :term:`Response` object +directly. It may return another arbitrary non-Response value, +however, this return value must be converted into a :term:`Response` +object by the :term:`renderer` associated with the :term:`view configuration` for the view. -View callables can be functions, instances, or classes. View -callables can optionally be defined with an alternate calling -convention. +View callables can be functions, instances, or classes. .. index:: single: view calling convention @@ -67,7 +65,7 @@ Defining a View Callable as a Function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The easiest way to define a view callable is to create a function that -accepts a single argument named ``request`` and which returns a +accepts a single argument named ``request``, and which returns a :term:`Response` object. For example, this is a "hello world" view callable implemented as a function: @@ -97,10 +95,7 @@ created. Subsequently, that instance's ``__call__`` method is invoked with no parameters. Views defined as classes must have the following traits: -- an ``__init__`` method that accepts a ``request`` as its sole - positional argument or an ``__init__`` method that accepts two - arguments: ``request`` and ``context`` as per - :ref:`request_and_context_view_definitions`. +- an ``__init__`` method that accepts a ``request`` argument. - a ``__call__`` method that accepts no parameters and which returns a response. @@ -132,75 +127,74 @@ represent the method expected to return a response, you can use an .. _request_and_context_view_definitions: -Context-And-Request View Callable Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. sidebar:: Context-And-Request View Callable Definitions -Usually, view callables are defined to accept only a single argument: -``request``. However, view callables may alternately be defined as -classes or functions (or any callable) that accept *two* positional -arguments: a :term:`context` as the first argument and a -:term:`request` as the second argument. + Usually, view callables are defined to accept only a single argument: + ``request``. However, view callables may alternately be defined as + classes, functions, or any callable that accept *two* positional + arguments: a :term:`context` as the first argument and a + :term:`request` as the second argument. -The :term:`context` and :term:`request` arguments passed to a view -function defined in this style can be defined as follows: + The :term:`context` and :term:`request` arguments passed to a view + function defined in this style can be defined as follows: -context - An instance of a :term:`context` found via graph :term:`traversal` - or :term:`URL dispatch`. If the context is found via traversal, it - will be a :term:`model` object. + context + An instance of a :term:`context` found via graph :term:`traversal` + or :term:`URL dispatch`. If the context is found via traversal, it + will be a :term:`model` object. -request - A :app:`Pyramid` Request object representing the current WSGI - request. + request + A :app:`Pyramid` Request object representing the current WSGI + request. -The following types work as view callables in this style: + The following types work as view callables in this style: -#. Functions that accept two arguments: ``context``, and ``request``, - e.g.: + #. Functions that accept two arguments: ``context``, and ``request``, + e.g.: - .. code-block:: python - :linenos: + .. code-block:: python + :linenos: - from pyramid.response import Response + from pyramid.response import Response - def view(context, request): - return Response('OK') + def view(context, request): + return Response('OK') -#. Classes that have an ``__init__`` method that accepts ``context, - request`` and a ``__call__`` which accepts no arguments, e.g.: + #. Classes that have an ``__init__`` method that accepts ``context, + request`` and a ``__call__`` which accepts no arguments, e.g.: - .. code-block:: python - :linenos: + .. code-block:: python + :linenos: - from pyramid.response import Response + from pyramid.response import Response - class view(object): - def __init__(self, context, request): - self.context = context - self.request = request + class view(object): + def __init__(self, context, request): + self.context = context + self.request = request - def __call__(self): - return Response('OK') + def __call__(self): + return Response('OK') -#. Arbitrary callables that have a ``__call__`` method that accepts - ``context, request``, e.g.: + #. Arbitrary callables that have a ``__call__`` method that accepts + ``context, request``, e.g.: - .. code-block:: python - :linenos: + .. code-block:: python + :linenos: - from pyramid.response import Response + from pyramid.response import Response - class View(object): - def __call__(self, context, request): - return Response('OK') - view = View() # this is the view callable + class View(object): + def __call__(self, context, request): + return Response('OK') + view = View() # this is the view callable -This style of calling convention is most useful for :term:`traversal` -based applications, where the context object is frequently used within -the view callable code itself. + This style of calling convention is most useful for :term:`traversal` + based applications, where the context object is frequently used within + the view callable code itself. -No matter which view calling convention is used, the view code always -has access to the context via ``request.context``. + No matter which view calling convention is used, the view code always + has access to the context via ``request.context``. .. index:: single: view response @@ -288,8 +282,8 @@ and renderers which use templating systems. See also .. _http_redirect: -Using a View Callable to Do A HTTP Redirect -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Using a View Callable to Do an HTTP Redirect +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can issue an HTTP redirect from within a view by returning a particular kind of response. @@ -308,6 +302,19 @@ See :mod:`pyramid.httpexceptions` for the documentation for the ``HTTPFound`` exception; it also includes other response types that imply other HTTP response codes, such as ``HTTPUnauthorized`` for ``401 Unauthorized``. +.. note:: + + Although exception types from the :mod:`pyramid.httpexceptions` module are + in fact bona fide Python :class:`Exception` types, the :app:`Pyramid` view + machinery expects them to be *returned* by a view callable rather than + *raised*. + + It is possible, however, in Python 2.5 and above, to configure an + *exception view* to catch these exceptions, and return an appropriate + :class:`pyramid.response.Response`. The simplest such view could just + catch and return the original exception. See :ref:`exception_views` for + more details. + .. index:: single: renderer single: view renderer @@ -379,7 +386,7 @@ Additional renderers can be added to the system as necessary (see Built-In Renderers ~~~~~~~~~~~~~~~~~~ -Several built-in "renderers" exist in :app:`Pyramid`. These +Several built-in renderers exist in :app:`Pyramid`. These renderers can be used in the ``renderer`` attribute of view configurations. @@ -429,14 +436,13 @@ attributes by attaching properties to the request. See ``json``: JSON Renderer +++++++++++++++++++++++ -The ``json`` renderer is a renderer which renders view callable -results to :term:`JSON`. If a view callable returns a non-Response -object it is called. It passes the return value through the +The ``json`` renderer renders view callable +results to :term:`JSON`. It passes the return value through the ``json.dumps`` standard library function, and wraps the result in a response object. It also sets the response content-type to ``application/json``. -Here's an example of a view that returns a dictionary. If the +Here's an example of a view that returns a dictionary. Since the ``json`` renderer is specified in the configuration for this view, the view will render the returned dictionary to a JSON serialization: @@ -561,19 +567,21 @@ attaching properties to the request. See ``*.mak`` or ``*.mako``: Mako Template Renderer +++++++++++++++++++++++++++++++++++++++++++++++ -The ``Mako`` template renderer is a renderer which renders a Mako template. +The ``Mako`` template renderer renders views using a Mako template. When used, the view must return a Response object or a Python *dictionary*. The dictionary items will then be used in the global template space. If the -view callable returns anything but a Response object or a dictionary, an error +view callable returns anything but a Response object, or a dictionary, an error will be raised. -When using the ``renderer`` attribute to specify a Mako template, the template -can be specified in two ways. First, a relative path can be used to name a -Mako template relative to the configured Mako template directories. Second, a -:term:`resource specification` can be used to locate a template to render. -These two styles of naming a template to render also carry through to Mako -templates, so that Mako template's can inherit using a :term:`resource -specification` if desired. +When using a ``renderer`` argument to a :term:`view configuration` to +specify a Mako template, the value of the ``renderer`` may be a path +relative to the ``mako.directories`` setting (e.g. +``some/template.mak``) or, alternately, it may be a :term:`resource +specification` (e.g. ``apackage:templates/sometemplate.mak``). Mako +templates may internally inherit other Mako templates using a relative +filename or a :term:`resource specification` as desired. + +XXX Further explanation or link to mako inheritance info Here's an example view configuration which uses a relative path: @@ -620,14 +628,13 @@ additional :ref:`mako_template_renderer_settings`. Varying Attributes of Rendered Responses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Before a response that is constructed as the result of the use of a -:term:`renderer` is returned to :app:`Pyramid`, several attributes -of the request are examined which have the potential to influence -response behavior. +Before a response constructed by a :term:`renderer` is returned to +:app:`Pyramid`, several attributes of the request are examined which +have the potential to influence response behavior. View callables that don't directly return a response should set these -values on the ``request`` object via ``setattr`` within the view -callable to influence associated response attributes. +attributes on the ``request`` object via ``setattr`` during their +execution, to influence associated response attributes. ``response_content_type`` Defines the content-type of the resulting response, @@ -678,7 +685,7 @@ Adding and Overriding Renderers New templating systems and serializers can be associated with :app:`Pyramid` renderer names. To this end, configuration declarations can be made which -override an existing :term:`renderer factory` and which add a new renderer +override an existing :term:`renderer factory`, and which add a new renderer factory. Renderers can be registered imperatively using the @@ -707,10 +714,10 @@ to such an object. Adding a New Renderer +++++++++++++++++++++ -You may a new renderer by creating and registering a :term:`renderer +You may add a new renderer by creating and registering a :term:`renderer factory`. -A renderer factory implementation is usually a class which has the +A renderer factory implementation is typically a class with the following interface: .. code-block:: python @@ -739,8 +746,8 @@ factory constructor is available as :class:`pyramid.interfaces.IRendererInfo`. There are essentially two different kinds of renderer factories: -- A renderer factory which expects to accept a :term:`resource specification` - or an absolute path as the ``name`` attribute of the ``info`` object fed to +- A renderer factory which expects to accept a :term:`resource specification`, + or an absolute path, as the ``name`` attribute of the ``info`` object fed to its constructor. These renderer factories are registered with a ``name`` value that begins with a dot (``.``). These types of renderer factories usually relate to a file on the filesystem, such as a template. @@ -770,10 +777,11 @@ Here's an example of the registration of a simple renderer factory via config.add_renderer(name='amf', factory='my.package.MyAMFRenderer') -Adding the above code to your application startup configuration will allow -you to use the ``my.package.MyAMFRenderer`` renderer factory implementation -in view configurations by referring to it as ``amf`` in the ``renderer`` -attribute of a :term:`view configuration`: +Adding the above code to your application startup configuration will +allow you to use the ``my.package.MyAMFRenderer`` renderer factory +implementation in view configurations. Your application can use this +renderer by specifying ``amf`` in the ``renderer`` attribute of a +:term:`view configuration`: .. code-block:: python :linenos: @@ -784,13 +792,12 @@ attribute of a :term:`view configuration`: def myview(request): return {'Hello':'world'} -At startup time, when a :term:`view configuration` is encountered -which has a ``name`` argument that does not contain a dot, such as the -above ``amf`` is encountered, the full value of the ``name`` attribute -is used to construct a renderer from the associated renderer factory. -In this case, the view configuration will create an instance of an -``AMFRenderer`` for each view configuration which includes ``amf`` as -its renderer value. The ``name`` passed to the ``AMFRenderer`` +At startup time, when a :term:`view configuration` is encountered, which +has a ``name`` attribute that does not contain a dot, the full ``name`` +value is used to construct a renderer from the associated renderer +factory. In this case, the view configuration will create an instance +of an ``AMFRenderer`` for each view configuration which includes ``amf`` +as its renderer value. The ``name`` passed to the ``AMFRenderer`` constructor will always be ``amf``. Here's an example of the registration of a more complicated renderer @@ -816,17 +823,17 @@ the ``renderer`` attribute of a :term:`view configuration`: def myview(request): return {'Hello':'world'} -When a :term:`view configuration` which has a ``name`` attribute that does -contain a dot, such as ``templates/mytemplate.jinja2`` above is encountered -at startup time, the value of the name attribute is split on its final dot. -The second element of the split is typically the filename extension. This -extension is used to look up a renderer factory for the configured view. -Then the value of ``renderer`` is passed to the factory to create a renderer -for the view. In this case, the view configuration will create an instance -of a ``Jinja2Renderer`` for each view configuration which includes anything -ending with ``.jinja2`` as its ``renderer`` value. The ``name`` passed to -the ``Jinja2Renderer`` constructor will be whatever the user passed as -``renderer=`` to the view configuration. +When a :term:`view configuration` is encountered at startup time, which +has a ``name`` attribute that does contain a dot, the value of the name +attribute is split on its final dot. The second element of the split is +typically the filename extension. This extension is used to look up a +renderer factory for the configured view. Then the value of +``renderer`` is passed to the factory to create a renderer for the view. +In this case, the view configuration will create an instance of a +``Jinja2Renderer`` for each view configuration which includes anything +ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed +to the ``Jinja2Renderer`` constructor will be the full value that was +set as ``renderer=`` in the view configuration. See also :ref:`renderer_directive` and :meth:`pyramid.configuration.Configurator.add_renderer`. @@ -861,9 +868,9 @@ After you do this, the :term:`renderer factory` in ``mypackage.pt_renderer`` will be used to render templates which end in ``.pt``, replacing the default Chameleon ZPT renderer. -To associate a *default* renderer with *all* view configurations (even ones -which do not possess a ``renderer`` attribute), use a variation on the -following (ie. pass ``None`` as the ``name`` attribute to the renderer tag): +To associate a *default* renderer with *all* view configurations (even +ones which do not possess a ``renderer`` attribute), pass ``None`` as +the ``name`` attribute to the renderer tag: .. code-block:: python :linenos: @@ -970,25 +977,24 @@ The above exception view names the ``route_name`` of ``home``, meaning that it will only be called when the route matched has a name of ``home``. You can therefore have more than one exception view for any given exception in the system: the "most specific" one will be called -when the set of request circumstances which match the view -registration. +when the set of request circumstances match the view registration. -The only view predicate that cannot be not be used successfully when -creating an exception view configuration is ``name``. The name used -to look up an exception view is always the empty string. Views -registered as exception views which have a name will be ignored. +The only view predicate that cannot be used successfully when creating +an exception view configuration is ``name``. The name used to look up +an exception view is always the empty string. Views registered as +exception views which have a name will be ignored. .. note:: - Normal (non-exception) views registered against a context which + Normal (i.e., non-exception) views registered against a context which inherits from :exc:`Exception` will work normally. When an - exception view configuraton is processed, *two* views are + exception view configuration is processed, *two* views are registered. One as a "normal" view, the other as an "exception" view. This means that you can use an exception as ``context`` for a normal view. -The feature can be used with any view registration mechanism -(``@view_config`` decorator, ZCML, or imperative ``add_view`` styles). +Exception views can be configured with any view registration mechanism: +``@view_config`` decorator, ZCML, or imperative ``add_view`` styles. .. index:: single: unicode, views, and forms @@ -1010,19 +1016,29 @@ implementations, and handling form submission data is a property of the request implementation. Understanding WebOb's request API is the key to understanding how to process form submission data. -There are some defaults that you need to be aware of when trying to handle form -submission data in a :app:`Pyramid` view. Because having high-order -(non-ASCII) characters in data contained within form submissions is exceedingly -common, and because the UTF-8 encoding is the most common encoding used on the -web for non-ASCII character data, and because working and storing Unicode -values is much saner than working with and storing bytestrings, :app:`Pyramid` +There are some defaults that you need to be aware of when trying to +handle form submission data in a :app:`Pyramid` view. Having high-order +(i.e., non-ASCII) characters in data contained within form submissions +is exceedingly common, and the UTF-8 encoding is the most common +encoding used on the web for character data. Since Unicode values are +much saner than working with and storing bytestrings, :app:`Pyramid` configures the :term:`WebOb` request machinery to attempt to decode form -submission values into Unicode from the UTF-8 character set implicitly. This -implicit decoding happens when view code obtains form field values via the -``request.params``, ``request.GET``, or ``request.POST`` APIs (see -:ref:`request_module` for details about these APIs). +submission values into Unicode from UTF-8 implicitly. +This implicit decoding happens when view code obtains form field values +via the ``request.params``, ``request.GET``, or ``request.POST`` APIs +(see :ref:`request_module` for details about these APIs). -For example, let's assume that the following form page is served up to +.. note:: + Many people find the difference between Unicode and UTF-8 confusing. + Unicode is a standard for representing text that supports most of the + world's writing systems. However, there are many ways that Unicode + data can be encoded into bytes for transmittal and storage. UTF-8 is + a specific encoding for Unicode, that is backwards-compatible with + ASCII. This makes UTF-8 very convenient for encoding data where a + large subset of that data is ASCII characters, which is largely true + on the web. UTF-8 is also the standard character encoding for URLs. + +As an example, let's assume that the following form page is served up to a browser client, and its ``action`` points at some :app:`Pyramid` view code: @@ -1069,22 +1085,24 @@ decode already-decoded (``unicode``) values obtained from firstname = request.params['firstname'].decode('utf-8') lastname = request.params['lastname'].decode('utf-8') -For implicit decoding to work reliably, you should ensure that every form you -render that posts to a :app:`Pyramid` view is rendered via a response that has -a ``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form above, -with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within -the HTML ``head`` of the page containing the form. This must be done -explicitly because all known browser clients assume that they should encode -form data in the character set implied by ``Content-Type`` value of the -response containing the form when subsequently submitting that form; there is -no other generally accepted way to tell browser clients which charset to use to -encode form data. If you do not specify an encoding explicitly, the browser -client will choose to encode form data in its default character set before -submitting it. The browser client may have a non-UTF-8 default encoding. If -such a request is handled by your view code, when the form submission data is -encoded in a non-UTF8 charset, eventually the request code accessed within your -view will throw an error when it can't decode some high-order character encoded -in another character set within form data e.g. when +For implicit decoding to work reliably, you should ensure that every +form you render that posts to a :app:`Pyramid` view explicitly defines a +charset encoding of UTF-8. This can be done via a response that has a +``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form +above, with a ``meta http-equiv`` tag that implies that the charset is +UTF-8 within the HTML ``head`` of the page containing the form. This +must be done explicitly because all known browser clients assume that +they should encode form data in the same character set implied by +``Content-Type`` value of the response containing the form when +subsequently submitting that form. There is no other generally accepted +way to tell browser clients which charset to use to encode form data. +If you do not specify an encoding explicitly, the browser client will +choose to encode form data in its default character set before +submitting it, which may not be UTF-8 as the server expects. If a +request containing form data encoded in a non-UTF8 charset is handled by +your view code, eventually the request code accessed within your view +will throw an error when it can't decode some high-order character +encoded in another character set within form data, e.g., when ``request.params['somename']`` is accessed. If you are using the :class:`pyramid.response.Response` class to generate a @@ -1092,14 +1110,14 @@ response, or if you use the ``render_template_*`` templating APIs, the UTF-8 charset is set automatically as the default via the ``Content-Type`` header. If you return a ``Content-Type`` header without an explicit charset, a request will add a ``;charset=utf-8`` trailer to the ``Content-Type`` header value for -you for response content types that are textual (e.g. ``text/html``, +you, for response content types that are textual (e.g. ``text/html``, ``application/xml``, etc) as it is rendered. If you are using your own response object, you will need to ensure you do this yourself. .. note:: Only the *values* of request params obtained via ``request.params``, ``request.GET`` or ``request.POST`` are decoded to Unicode objects implicitly in the :app:`Pyramid` default - configuration. The keys are still strings. + configuration. The keys are still (byte) strings. .. index:: single: view configuration @@ -1112,7 +1130,7 @@ View Configuration: Mapping a Context to a View 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 -about the set of circumstances which must be true for the view +that 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 @@ -1246,6 +1264,10 @@ Non-Predicate Arguments 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 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. @@ -1254,7 +1276,7 @@ Predicate Arguments default view). ``context`` - An object representing Python class that the :term:`context` must be + An object representing a Python class that the :term:`context` must be an instance of, *or* the :term:`interface` that the :term:`context` must provide in order for this view to be found and called. This predicate is true when the :term:`context` is an instance of the @@ -1271,14 +1293,15 @@ Predicate Arguments 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 ``route_name`` usually has 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 + 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 be have a - chance of being invoked for when the :term:`triad` includes a - request object that does not indicate it matched a route. + chance of being invoked if no other route was matched. This is when + the request object of the :term:`triad` does not indicate it matched + any configured route. ``request_type`` This value should be an :term:`interface` that the :term:`request` @@ -1319,9 +1342,10 @@ Predicate Arguments ``containment`` This value should be a reference to a Python class or - :term:`interface` that a parent object in the :term:`lineage` must - provide in order for this view to be found and called. The nodes in - your object graph must be "location-aware" to use this feature. + :term:`interface` that a parent object in the context's + :term:`lineage` must provide in order for this view to be found and + called. The nodes in your object graph 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 @@ -1480,11 +1504,13 @@ All arguments to ``view_config`` may be omitted. For example: Such a registration as the one directly above implies that the view name will be ``my_view``, registered with a ``context`` argument that matches any model type, using no permission, registered against -requests with any request method / request type / request param / -route name / containment. +requests with any 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. To make :app:`Pyramid` process your +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* do use the ``scan`` method of a :class:`pyramid.configuration.Configurator`: @@ -1602,7 +1628,7 @@ When the decorator is used against a class method, 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`` as per :ref:`request_and_context_view_definitions`. +request``. The method which is decorated must return a :term:`response` or it must rely on a :term:`renderer` to generate one. @@ -1721,12 +1747,12 @@ in such a way that the interface is attached to it. alsoProvides(hello, IHello) return hello -Regardless of how you associate an interface with a model instance or a model +Regardless of how you associate an interface, with a model instance, or a model 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 "models.py", the -below interface declaration will associate the -``mypackage.views.hello_world`` view with models that implement (aka provide) +interface declaration below will associate the +``mypackage.views.hello_world`` view with models that implement, or provide, this interface. .. code-block:: python @@ -1741,11 +1767,13 @@ Any time a model 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. -Note that views registered against a model class take precedence over views -registered for any interface the model class implements when an ambiguity -arises. If a view is registered for both the class type of the context and -an interface implemented by the context's class, the view registered for the -context's class will "win". +Note, in cases where a view is registered against a model class, and a +view is also registered against an interface that the model class +implements, an ambiguity arises. Views registered for the model class +take precedence over any views registered for any interface the model +class implements. Thus, if a view is registered for both the class type +of the context and an interface implemented by the context's class, the +view registered for the context's class will "win". For more information about defining models with interfaces for use within view configuration, see :ref:`models_which_implement_interfaces`. @@ -1759,11 +1787,12 @@ view configuration, see :ref:`models_which_implement_interfaces`. Configuring View Security ~~~~~~~~~~~~~~~~~~~~~~~~~ -If a :term:`authorization policy` is active, any :term:`permission` attached -to a :term:`view configuration` found during view lookup will be consulted to -ensure that the currently authenticated user possesses that permission -against the :term:`context` before the view function is actually called. -Here's an example of specifying a permission in a view configuration using +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` before the view +function is actually called. Here's an example of specifying a +permission in a view configuration using :meth:`pyramid.configuration.Configurator.add_view`: .. code-block:: python @@ -1774,11 +1803,11 @@ Here's an example of specifying a permission in a view configuration using config.add_view('myproject.views.add_entry', name='add.html', context='myproject.models.IBlog', permission='add') -When an authentication 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` and an -authorization policy is enabled. Instead the :term:`forbidden view` result -will be returned to the client as per :ref:`protecting_views`. +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`. .. index:: single: view lookup @@ -1792,7 +1821,7 @@ View Lookup and Invocation finding an invoking a :term:`view callable`. The view lookup subsystem is passed a :term:`context`, a :term:`view name`, and the :term:`request` object. These three bits of information are referred -to within this chapter as a :term:`triad`. +to within this chapter as the :term:`triad`. :term:`View configuration` information stored within in the :term:`application registry` is compared against a triad by the view @@ -1817,7 +1846,7 @@ 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 which has predicates which allow it to be +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 @@ -1839,5 +1868,5 @@ misconfiguration. To debug these errors, use the 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. +more information about how, and where to set these values. |
