diff options
| author | Christoph Zwerschke <cito@online.de> | 2016-04-19 20:07:12 +0200 |
|---|---|---|
| committer | Christoph Zwerschke <cito@online.de> | 2016-04-19 20:07:12 +0200 |
| commit | 3629c49e46207ff5162a82883c14937e6ef4c186 (patch) | |
| tree | 1306181202cb8313f16080789f5b9ab1eeb61d53 /docs/narr/views.rst | |
| parent | 804ba0b2f434781e77d2b5191f1cd76a490f6610 (diff) | |
| parent | 6c16fb020027fac47e4d2e335cd9e264dba8aa3b (diff) | |
| download | pyramid-3629c49e46207ff5162a82883c14937e6ef4c186.tar.gz pyramid-3629c49e46207ff5162a82883c14937e6ef4c186.tar.bz2 pyramid-3629c49e46207ff5162a82883c14937e6ef4c186.zip | |
Merge remote-tracking branch 'refs/remotes/Pylons/master'
Diffstat (limited to 'docs/narr/views.rst')
| -rw-r--r-- | docs/narr/views.rst | 637 |
1 files changed, 351 insertions, 286 deletions
diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 5c9bd91af..770d27919 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -3,62 +3,45 @@ Views ===== -One of the primary jobs of :app:`Pyramid` is to find and invoke a -:term:`view callable` when a :term:`request` reaches your application. View -callables are bits of code which do something interesting in response to a -request made to your application. +One of the primary jobs of :app:`Pyramid` is to find and invoke a :term:`view +callable` when a :term:`request` reaches your application. View callables are +bits of code which do something interesting in response to a request made to +your application. They are the "meat" of any interesting web application. -.. note:: +.. note:: A :app:`Pyramid` :term:`view callable` is often referred to in - conversational shorthand as a :term:`view`. In this documentation, - however, we need to use less ambiguous terminology because there - are significant differences between view *configuration*, the code - that implements a view *callable*, and the process of view - *lookup*. - -The :ref:`urldispatch_chapter`, and :ref:`traversal_chapter` chapters -describes how, using information from the :term:`request`, a -:term:`context` resource is computed. But the context resource itself -isn't very useful without an associated :term:`view callable`. A view -callable returns a response to a user, often using the context resource -to do so. - -The job of actually locating and invoking the "best" :term:`view callable` is -the job of the :term:`view lookup` subsystem. The view lookup subsystem -compares the resource supplied by :term:`resource location` and information -in the :term:`request` against :term:`view configuration` statements made by -the developer to choose the most appropriate view callable for a specific -set of circumstances. - -This chapter describes how view callables work. In the -:ref:`view_config_chapter` chapter, there are details about performing -view configuration, and a detailed explanation of view lookup. + conversational shorthand as a :term:`view`. In this documentation, however, + we need to use less ambiguous terminology because there are significant + differences between view *configuration*, the code that implements a view + *callable*, and the process of view *lookup*. + +This chapter describes how view callables should be defined. We'll have to wait +until a following chapter (entitled :ref:`view_config_chapter`) to find out how +we actually tell :app:`Pyramid` to wire up view callables to particular URL +patterns and other request circumstances. + +.. index:: + single: view callables View Callables -------------- -View callables are, at the risk of sounding obvious, callable Python -objects. Specifically, view callables can be functions, classes, or -instances that implement an ``__call__`` method (making the -instance callable). - -View callables must, at a minimum, accept a single argument named -``request``. This argument represents a :app:`Pyramid` :term:`Request` -object. A request object encapsulates a WSGI environment provided to -:app:`Pyramid` by the upstream :term:`WSGI` server. As you might expect, -the request object contains everything your application needs to know -about the specific HTTP request being made. - -A view callable's ultimate responsibility is to create a :mod:`Pyramid` -:term:`Response` object. This can be done by creating the response -object in the view callable code and returning it directly, as we will -be doing in this chapter. However, if a view callable does not return a -response itself, it can be configured to use a :term:`renderer` that -converts its return value into a :term:`Response` object. Using -renderers is the common way that templates are used with view callables -to generate markup. See the :ref:`renderers_chapter` chapter for -details. +View callables are, at the risk of sounding obvious, callable Python objects. +Specifically, view callables can be functions, classes, or instances that +implement a ``__call__`` method (making the instance callable). + +View callables must, at a minimum, accept a single argument named ``request``. +This argument represents a :app:`Pyramid` :term:`Request` object. A request +object represents a :term:`WSGI` environment provided to :app:`Pyramid` by the +upstream WSGI server. As you might expect, the request object contains +everything your application needs to know about the specific HTTP request being +made. + +A view callable's ultimate responsibility is to create a :app:`Pyramid` +:term:`Response` object. This can be done by creating a :term:`Response` object +in the view callable code and returning it directly or by raising special kinds +of exceptions from within the body of a view callable. .. index:: single: view calling convention @@ -92,17 +75,17 @@ Defining a View Callable as a Class ----------------------------------- A view callable may also be represented by a Python class instead of a -function. When a view callable is a class, the calling semantics are -slightly different than when it is a function or another non-class callable. -When a view callable is a class, the class' ``__init__`` method is called with a +function. When a view callable is a class, the calling semantics are slightly +different than when it is a function or another non-class callable. When a view +callable is a class, the class's ``__init__`` method is called with a ``request`` parameter. As a result, an instance of the class is created. Subsequently, that instance's ``__call__`` method is invoked with no -parameters. Views defined as classes must have the following traits: +parameters. Views defined as classes must have the following traits. -- an ``__init__`` method that accepts a ``request`` argument. +- an ``__init__`` method that accepts a ``request`` argument -- a ``__call__`` (or other) method that accepts no parameters and which - returns a response. +- a ``__call__`` (or other) method that accepts no parameters and which returns + a response For example: @@ -122,91 +105,12 @@ The request object passed to ``__init__`` is the same type of request object described in :ref:`function_as_view`. If you'd like to use a different attribute than ``__call__`` to represent the -method expected to return a response, you can use an ``attr`` value as part -of the configuration for the view. See :ref:`view_configuration_parameters`. -The same view callable class can be used in different view configuration -statements with different ``attr`` values, each pointing at a different -method of the class if you'd like the class to represent a collection of -related view callables. - -.. note:: A package named :term:`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 calling convention - -.. _request_and_context_view_definitions: - -Alternate View Callable Argument/Calling Conventions ----------------------------------------------------- - -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` resource 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: - -context - - The :term:`resource` object found via tree :term:`traversal` or :term:`URL - dispatch`. - -request - A :app:`Pyramid` Request object representing the current WSGI request. - -The following types work as view callables in this style: - -#. Functions that accept two arguments: ``context``, and ``request``, - e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - def view(context, request): - return Response('OK') - -#. Classes that have an ``__init__`` method that accepts ``context, - request`` and a ``__call__`` method which accepts no arguments, e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - class view(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return Response('OK') - -#. Arbitrary callables that have a ``__call__`` method that accepts - ``context, request``, e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - 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. - -No matter which view calling convention is used, the view code always has -access to the context via ``request.context``. +method expected to return a response, you can use an ``attr`` value as part of +the configuration for the view. See :ref:`view_configuration_parameters`. The +same view callable class can be used in different view configuration statements +with different ``attr`` values, each pointing at a different method of the +class if you'd like the class to represent a collection of related view +callables. .. index:: single: view response @@ -230,117 +134,138 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -You don't need to always use :class:`~pyramid.response.Response` to represent -a response. :app:`Pyramid` provides a range of different "exception" classes -which can act as response objects too. For example, an instance of the class +:app:`Pyramid` provides a range of different "exception" classes which inherit +from :class:`pyramid.response.Response`. For example, an instance of the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response object -(see :ref:`http_redirect`). A view can actually return any object that has -the following attributes. +because it inherits from :class:`~pyramid.response.Response`. For examples, +see :ref:`http_exceptions` and :ref:`http_redirect`. -status - The HTTP status code (including the name) for the response as a string. - E.g. ``200 OK`` or ``401 Unauthorized``. +.. note:: -headerlist - A sequence of tuples representing the list of headers that should be - set in the response. E.g. ``[('Content-Type', 'text/html'), - ('Content-Length', '412')]`` + You can also return objects from view callables that aren't instances of + :class:`pyramid.response.Response` in various circumstances. This can be + helpful when writing tests and when attempting to share code between view + callables. See :ref:`renderers_chapter` for the common way to allow for + this. A much less common way to allow for view callables to return + non-Response objects is documented in :ref:`using_iresponse`. -app_iter - An iterable representing the body of the response. This can be a - list, e.g. ``['<html><head></head><body>Hello - world!</body></html>']`` or it can be a file-like object, or any - other sort of iterable. +.. index:: + single: view exceptions + +.. _special_exceptions_in_callables: -These attributes form the structure of the "Pyramid Response interface". +Using Special Exceptions in View Callables +------------------------------------------ + +Usually when a Python exception is raised within a view callable, +:app:`Pyramid` allows the exception to propagate all the way out to the +:term:`WSGI` server which invoked the application. It is usually caught and +logged there. + +However, for convenience, a special set of exceptions exists. When one of +these exceptions is raised within a view callable, it will always cause +:app:`Pyramid` to generate a response. These are known as :term:`HTTP +exception` objects. .. index:: - single: view http redirect - single: http redirect (from a view) + single: HTTP exceptions -.. _http_redirect: +.. _http_exceptions: -Using a View Callable to Do an HTTP Redirect --------------------------------------------- +HTTP Exceptions +~~~~~~~~~~~~~~~ + +All :mod:`pyramid.httpexceptions` classes which are documented as inheriting +from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http +exception` objects. Instances of an HTTP exception object may either be +*returned* or *raised* from within view code. In either case (return or raise) +the instance will be used as the view's response. -You can issue an HTTP redirect from within a view by returning a particular -kind of response. +For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception can +be raised. This will cause a response to be generated with a ``401 +Unauthorized`` status: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPFound + from pyramid.httpexceptions import HTTPUnauthorized - def myview(request): - return HTTPFound(location='http://example.com') + def aview(request): + raise HTTPUnauthorized() -All exception types from the :mod:`pyramid.httpexceptions` module implement -the :term:`Response` interface; any can be returned as the response from a -view. 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``. +An HTTP exception, instead of being raised, can alternately be *returned* (HTTP +exceptions are also valid response objects): -.. note:: +.. code-block:: python + :linenos: - 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*. + from pyramid.httpexceptions import HTTPUnauthorized - 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. + def aview(request): + return HTTPUnauthorized() -.. index:: - single: view exceptions +A shortcut for creating an HTTP exception is the +:func:`pyramid.httpexceptions.exception_response` function. This function +accepts an HTTP status code and returns the corresponding HTTP exception. For +example, instead of importing and constructing a +:class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can use +the :func:`~pyramid.httpexceptions.exception_response` function to construct +and return the same object. -.. _special_exceptions_in_callables: +.. code-block:: python + :linenos: -Using Special Exceptions In View Callables ------------------------------------------- + from pyramid.httpexceptions import exception_response -Usually when a Python exception is raised within a view callable, -:app:`Pyramid` allows the exception to propagate all the way out to the -:term:`WSGI` server which invoked the application. + def aview(request): + raise exception_response(401) + +This is the case because ``401`` is the HTTP status code for "HTTP +Unauthorized". Therefore, ``raise exception_response(401)`` is functionally +equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each HTTP +response code to its purpose and its associated HTTP exception object is +provided within :mod:`pyramid.httpexceptions`. -However, for convenience, two special exceptions exist which are always -handled by :app:`Pyramid` itself. These are -:exc:`pyramid.exceptions.NotFound` and :exc:`pyramid.exceptions.Forbidden`. -Both are exception classes which accept a single positional constructor -argument: a ``message``. +.. versionadded:: 1.1 + The :func:`~pyramid.httpexceptions.exception_response` function. -If :exc:`~pyramid.exceptions.NotFound` is raised within view code, the result -of the :term:`Not Found View` will be returned to the user agent which -performed the request. +How Pyramid Uses HTTP Exceptions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :exc:`~pyramid.exceptions.Forbidden` is raised within view code, the result -of the :term:`Forbidden View` will be returned to the user agent which -performed the request. +HTTP exceptions are meant to be used directly by application developers. +However, Pyramid itself will raise two HTTP exceptions at various points during +normal operations. -In all cases, the message provided to the exception constructor is made -available to the view which :app:`Pyramid` invokes as -``request.exception.args[0]``. +* :exc:`~pyramid.httpexceptions.HTTPNotFound` gets raised when a view to + service a request is not found. +* :exc:`~pyramid.httpexceptions.HTTPForbidden` gets raised when authorization + was forbidden by a security policy. + +If :exc:`~pyramid.httpexceptions.HTTPNotFound` is raised by Pyramid itself or +within view code, the result of the :term:`Not Found View` will be returned to +the user agent which performed the request. + +If :exc:`~pyramid.httpexceptions.HTTPForbidden` is raised by Pyramid itself +within view code, the result of the :term:`Forbidden View` will be returned to +the user agent which performed the request. .. index:: single: exception views .. _exception_views: -Exception Views ---------------- +Custom Exception Views +---------------------- -The machinery which allows the special :exc:`~pyramid.exceptions.NotFound` and -:exc:`~pyramid.exceptions.Forbidden` exceptions to be caught by specialized -views as described in :ref:`special_exceptions_in_callables` can also be used -by application developers to convert arbitrary exceptions to responses. +The machinery which allows HTTP exceptions to be raised and caught by +specialized views as described in :ref:`special_exceptions_in_callables` can +also be used by application developers to convert arbitrary exceptions to +responses. To register a view that should be called whenever a particular exception is -raised from with :app:`Pyramid` view code, use the exception class or one of -its superclasses as the ``context`` of a view configuration which points at a -view callable you'd like to generate a response. +raised from within :app:`Pyramid` view code, use the exception class (or one of +its superclasses) as the :term:`context` of a view configuration which points +at a view callable for which you'd like to generate a response. For example, given the following exception class in a module named ``helloworld.exceptions``: @@ -359,6 +284,7 @@ raises a ``helloworld.exceptions.ValidationFailure`` exception: .. code-block:: python :linenos: + from pyramid.view import view_config from helloworld.exceptions import ValidationFailure @view_config(context=ValidationFailure) @@ -370,44 +296,91 @@ raises a ``helloworld.exceptions.ValidationFailure`` exception: Assuming that a :term:`scan` was run to pick up this view registration, this view callable will be invoked whenever a ``helloworld.exceptions.ValidationFailure`` is raised by your application's -view code. The same exception raised by a custom root factory or a custom -traverser is also caught and hooked. +view code. The same exception raised by a custom root factory, a custom +traverser, or a custom view or route predicate is also caught and hooked. -Other normal view predicates can also be used in combination with an -exception view registration: +Other normal view predicates can also be used in combination with an exception +view registration: .. code-block:: python :linenos: from pyramid.view import view_config - from pyramid.exceptions import NotFound - from pyramid.httpexceptions import HTTPNotFound + from helloworld.exceptions import ValidationFailure - @view_config(context=NotFound, route_name='home') - def notfound_view(request): - return HTTPNotFound() + @view_config(context=ValidationFailure, route_name='home') + def failed_validation(exc, request): + response = Response('Failed validation: %s' % exc.msg) + response.status_int = 500 + return response -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 +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 match the view registration. -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. +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 (i.e., non-exception) views registered against a context resource - type which inherits from :exc:`Exception` will work normally. When an - 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. + Normal (i.e., non-exception) views registered against a context resource type + which inherits from :exc:`Exception` will work normally. When an 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. Exception views can be configured with any view registration mechanism: -``@view_config`` decorator, ZCML, or imperative ``add_view`` styles. +``@view_config`` decorator or imperative ``add_view`` styles. + +.. note:: + + Pyramid's :term:`exception view` handling logic is implemented as a tween + factory function: :func:`pyramid.tweens.excview_tween_factory`. If Pyramid + exception view handling is desired, and tween factories are specified via + the ``pyramid.tweens`` configuration setting, the + :func:`pyramid.tweens.excview_tween_factory` function must be added to the + ``pyramid.tweens`` configuration setting list explicitly. If it is not + present, Pyramid will not perform exception view handling. + +.. index:: + single: view http redirect + single: http redirect (from a view) + +.. _http_redirect: + +Using a View Callable to do an HTTP Redirect +-------------------------------------------- + +You can issue an HTTP redirect by using the +:class:`pyramid.httpexceptions.HTTPFound` class. Raising or returning an +instance of this class will cause the client to receive a "302 Found" response. + +To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` instance. + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPFound + + def myview(request): + return HTTPFound(location='http://example.com') + +Alternately, you can *raise* an HTTPFound exception instead of returning one. + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPFound + + def myview(request): + raise HTTPFound(location='http://example.com') + +When the instance is raised, it is caught by the default :term:`exception +response` handler and turned into a response. .. index:: single: unicode, views, and forms @@ -422,34 +395,33 @@ various other clients. In :app:`Pyramid`, form submission handling logic is always part of a :term:`view`. For a general overview of how to handle form submission data using the :term:`WebOb` API, see :ref:`webob_chapter` and `"Query and POST variables" within the WebOb documentation -<http://pythonpaste.org/webob/reference.html#query-post-variables>`_. +<http://docs.webob.org/en/latest/reference.html#query-post-variables>`_. :app:`Pyramid` defers to WebOb for its request and response 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. 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 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). +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. 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 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). .. 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 transit 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. + 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 transit 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: @@ -474,8 +446,8 @@ browser client, and its ``action`` points at some :app:`Pyramid` view code: The ``myview`` view code in the :app:`Pyramid` application *must* expect that the values returned by ``request.params`` will be of type ``unicode``, as -opposed to type ``str``. The following will work to accept a form post from -the above form: +opposed to type ``str``. The following will work to accept a form post from the +above form: .. code-block:: python :linenos: @@ -503,30 +475,123 @@ encoding of UTF-8. This can be done via a response that has a 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. +form data in the same character set implied by the ``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-UTF-8 ``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 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``, ``application/xml``, etc) as it is rendered. If you are -using your own response object, you will need to ensure you do this yourself. +``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`` or ``application/xml``) 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 + (byte) strings. + + +.. index:: + single: view calling convention + +.. _request_and_context_view_definitions: + +Alternate View Callable Argument/Calling Conventions +---------------------------------------------------- + +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` resource 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: + +context + The :term:`resource` object found via tree :term:`traversal` or :term:`URL + dispatch`. + +request + A :app:`Pyramid` Request object representing the current WSGI request. + +The following types work as view callables in this style: + +#. Functions that accept two arguments: ``context`` and ``request``, e.g.: + + .. code-block:: python + :linenos: + + from pyramid.response import Response + + def view(context, request): + return Response('OK') + +#. Classes that have an ``__init__`` method that accepts ``context, request``, + and a ``__call__`` method which accepts no arguments, e.g.: + + .. code-block:: python + :linenos: -.. 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 (byte) strings. + from pyramid.response import Response + class view(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return Response('OK') + +#. Arbitrary callables that have a ``__call__`` method that accepts ``context, + request``, e.g.: + + .. code-block:: python + :linenos: + + from pyramid.response import Response + + 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. + +No matter which view calling convention is used, the view code always has +access to the context via ``request.context``. + +.. index:: + single: Passing in configuration variables + +.. _passing_in_config_variables: + +Passing Configuration Variables to a View +----------------------------------------- + +For information on passing a variable from the configuration .ini files to a +view, see :ref:`deployment_settings`. + +.. index:: + single: Pylons-style controller dispatch + +Pylons-1.0-Style "Controller" Dispatch +-------------------------------------- +A package named :term:`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. |
