diff options
Diffstat (limited to 'docs/narr/views.rst')
| -rw-r--r-- | docs/narr/views.rst | 235 |
1 files changed, 121 insertions, 114 deletions
diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 04d90fda8..ab6a108da 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: |
