1.. _views_chapter:
2
3Views
4=====
5
6One of the primary jobs of :app:`Pyramid` is to find and invoke a :term:`view
7callable` when a :term:`request` reaches your application.  View callables are
8bits of code which do something interesting in response to a request made to
9your application.  They are the "meat" of any interesting web application.
10
11.. note::
12
13   A :app:`Pyramid` :term:`view callable` is often referred to in
14   conversational shorthand as a :term:`view`.  In this documentation, however,
15   we need to use less ambiguous terminology because there are significant
16   differences between view *configuration*, the code that implements a view
17   *callable*, and the process of view *lookup*.
18
19This chapter describes how view callables should be defined. We'll have to wait
20until a following chapter (entitled :ref:`view_config_chapter`) to find out how
21we actually tell :app:`Pyramid` to wire up view callables to particular URL
22patterns and other request circumstances.
23
24.. index::
25   single: view callables
26
27View Callables
28--------------
29
30View callables are, at the risk of sounding obvious, callable Python objects.
31Specifically, view callables can be functions, classes, or instances that
32implement a ``__call__`` method (making the instance callable).
33
34View callables must, at a minimum, accept a single argument named ``request``.
35This argument represents a :app:`Pyramid` :term:`Request` object.  A request
36object represents a :term:`WSGI` environment provided to :app:`Pyramid` by the
37upstream WSGI server. As you might expect, the request object contains
38everything your application needs to know about the specific HTTP request being
39made.
40
41A view callable's ultimate responsibility is to create a :app:`Pyramid`
42:term:`Response` object. This can be done by creating a :term:`Response` object
43in the view callable code and returning it directly or by raising special kinds
44of exceptions from within the body of a view callable.
45
46.. index::
47   single: view calling convention
48   single: view function
49
50.. _function_as_view:
51
52Defining a View Callable as a Function
53--------------------------------------
54
55One of the easiest way to define a view callable is to create a function that
56accepts a single argument named ``request``, and which returns a
57:term:`Response` object.  For example, this is a "hello world" view callable
58implemented as a function:
59
60.. code-block:: python
61   :linenos:
62
63   from pyramid.response import Response
64
65   def hello_world(request):
66       return Response('Hello world!')
67
68.. index::
69   single: view calling convention
70   single: view class
71
72.. _class_as_view:
73
74Defining a View Callable as a Class
75-----------------------------------
76
77A view callable may also be represented by a Python class instead of a
78function.  When a view callable is a class, the calling semantics are slightly
79different than when it is a function or another non-class callable. When a view
80callable is a class, the class's ``__init__`` method is called with a
81``request`` parameter.  As a result, an instance of the class is created.
82Subsequently, that instance's ``__call__`` method is invoked with no
83parameters.  Views defined as classes must have the following traits.
84
85- an ``__init__`` method that accepts a ``request`` argument
86
87- a ``__call__`` (or other) method that accepts no parameters and which returns
88  a response
89
90For example:
91
92.. code-block:: python
93   :linenos:
94
95   from pyramid.response import Response
96
97   class MyView(object):
98       def __init__(self, request):
99           self.request = request
100
101       def __call__(self):
102           return Response('hello')
103
104The request object passed to ``__init__`` is the same type of request object
105described in :ref:`function_as_view`.
106
107If you'd like to use a different attribute than ``__call__`` to represent the
108method expected to return a response, you can use an ``attr`` value as part of
109the configuration for the view.  See :ref:`view_configuration_parameters`. The
110same view callable class can be used in different view configuration statements
111with different ``attr`` values, each pointing at a different method of the
112class if you'd like the class to represent a collection of related view
113callables.
114
115.. index::
116   single: view response
117   single: response
118
119.. _the_response:
120
121View Callable Responses
122-----------------------
123
124A view callable may return an object that implements the :app:`Pyramid`
125:term:`Response` interface.  The easiest way to return something that
126implements the :term:`Response` interface is to return a
127:class:`pyramid.response.Response` object instance directly.  For example:
128
129.. code-block:: python
130   :linenos:
131
132   from pyramid.response import Response
133
134   def view(request):
135       return Response('OK')
136
137:app:`Pyramid` provides a range of different "exception" classes which inherit
138from :class:`pyramid.response.Response`.  For example, an instance of the class
139:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object
140because it inherits from :class:`~pyramid.response.Response`.  For examples,
141see :ref:`http_exceptions` and :ref:`http_redirect`.
142
143.. note::
144
145   You can also return objects from view callables that aren't instances of
146   :class:`pyramid.response.Response` in various circumstances.  This can be
147   helpful when writing tests and when attempting to share code between view
148   callables.  See :ref:`renderers_chapter` for the common way to allow for
149   this.  A much less common way to allow for view callables to return
150   non-Response objects is documented in :ref:`using_iresponse`.
151
152.. index::
153   single: view exceptions
154
155.. _special_exceptions_in_callables:
156
157Using Special Exceptions in View Callables
158------------------------------------------
159
160Usually when a Python exception is raised within a view callable,
161:app:`Pyramid` allows the exception to propagate all the way out to the
162:term:`WSGI` server which invoked the application.  It is usually caught and
163logged there.
164
165However, for convenience, a special set of exceptions exists.  When one of
166these exceptions is raised within a view callable, it will always cause
167:app:`Pyramid` to generate a response.  These are known as :term:`HTTP
168exception` objects.
169
170.. index::
171   single: HTTP exceptions
172
173.. _http_exceptions:
174
175HTTP Exceptions
176~~~~~~~~~~~~~~~
177
178All :mod:`pyramid.httpexceptions` classes which are documented as inheriting
179from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http
180exception` objects.  Instances of an HTTP exception object may either be
181*returned* or *raised* from within view code.  In either case (return or raise)
182the instance will be used as the view's response.
183
184For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception can
185be raised.  This will cause a response to be generated with a ``401
186Unauthorized`` status:
187
188.. code-block:: python
189   :linenos:
190
191   from pyramid.httpexceptions import HTTPUnauthorized
192
193   def aview(request):
194       raise HTTPUnauthorized()
195
196An HTTP exception, instead of being raised, can alternately be *returned* (HTTP
197exceptions are also valid response objects):
198
199.. code-block:: python
200   :linenos:
201
202   from pyramid.httpexceptions import HTTPUnauthorized
203
204   def aview(request):
205       return HTTPUnauthorized()
206
207A shortcut for creating an HTTP exception is the
208:func:`pyramid.httpexceptions.exception_response` function.  This function
209accepts an HTTP status code and returns the corresponding HTTP exception. For
210example, instead of importing and constructing a
211:class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can use
212the :func:`~pyramid.httpexceptions.exception_response` function to construct
213and return the same object.
214
215.. code-block:: python
216   :linenos:
217
218   from pyramid.httpexceptions import exception_response
219
220   def aview(request):
221       raise exception_response(401)
222
223This is the case because ``401`` is the HTTP status code for "HTTP
224Unauthorized".  Therefore, ``raise exception_response(401)`` is functionally
225equivalent to ``raise HTTPUnauthorized()``.  Documentation which maps each HTTP
226response code to its purpose and its associated HTTP exception object is
227provided within :mod:`pyramid.httpexceptions`.
228
229.. versionadded:: 1.1
230   The :func:`~pyramid.httpexceptions.exception_response` function.
231
232How Pyramid Uses HTTP Exceptions
233~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
234
235HTTP exceptions are meant to be used directly by application developers.
236However, Pyramid itself will raise two HTTP exceptions at various points during
237normal operations.
238
239* :exc:`~pyramid.httpexceptions.HTTPNotFound` gets raised when a view to
240  service a request is not found.
241* :exc:`~pyramid.httpexceptions.HTTPForbidden` gets raised when authorization
242  was forbidden by a security policy.
243
244If :exc:`~pyramid.httpexceptions.HTTPNotFound` is raised by Pyramid itself or
245within view code, the result of the :term:`Not Found View` will be returned to
246the user agent which performed the request.
247
248If :exc:`~pyramid.httpexceptions.HTTPForbidden` is raised by Pyramid itself
249within view code, the result of the :term:`Forbidden View` will be returned to
250the user agent which performed the request.
251
252.. index::
253   single: exception views
254
255.. _exception_views:
256
257Custom Exception Views
258----------------------
259
260The machinery which allows HTTP exceptions to be raised and caught by
261specialized views as described in :ref:`special_exceptions_in_callables` can
262also be used by application developers to convert arbitrary exceptions to
263responses.
264
265To register a view that should be called whenever a particular exception is
266raised from within :app:`Pyramid` view code, use the exception class (or one of
267its superclasses) as the :term:`context` of a view configuration which points
268at a view callable for which you'd like to generate a response.
269
270For example, given the following exception class in a module named
271``helloworld.exceptions``:
272
273.. code-block:: python
274   :linenos:
275
276   class ValidationFailure(Exception):
277       def __init__(self, msg):
278           self.msg = msg
279
280
281You can wire a view callable to be called whenever any of your *other* code
282raises a ``helloworld.exceptions.ValidationFailure`` exception:
283
284.. code-block:: python
285   :linenos:
286
287   from pyramid.view import view_config
288   from helloworld.exceptions import ValidationFailure
289
290   @view_config(context=ValidationFailure)
291   def failed_validation(exc, request):
292       response =  Response('Failed validation: %s' % exc.msg)
293       response.status_int = 500
294       return response
295
296Assuming that a :term:`scan` was run to pick up this view registration, this
297view callable will be invoked whenever a
298``helloworld.exceptions.ValidationFailure`` is raised by your application's
299view code.  The same exception raised by a custom root factory, a custom
300traverser, or a custom view or route predicate is also caught and hooked.
301
302Other normal view predicates can also be used in combination with an exception
303view registration:
304
305.. code-block:: python
306   :linenos:
307
308   from pyramid.view import view_config
309   from helloworld.exceptions import ValidationFailure
310
311   @view_config(context=ValidationFailure, route_name='home')
312   def failed_validation(exc, request):
313       response =  Response('Failed validation: %s' % exc.msg)
314       response.status_int = 500
315       return response
316
317The above exception view names the ``route_name`` of ``home``, meaning that it
318will only be called when the route matched has a name of ``home``.  You can
319therefore have more than one exception view for any given exception in the
320system: the "most specific" one will be called when the set of request
321circumstances match the view registration.
322
323The only view predicate that cannot be used successfully when creating an
324exception view configuration is ``name``.  The name used to look up an
325exception view is always the empty string.  Views registered as exception views
326which have a name will be ignored.
327
328.. note::
329
330  Normal (i.e., non-exception) views registered against a context resource type
331  which inherits from :exc:`Exception` will work normally.  When an exception
332  view configuration is processed, *two* views are registered.  One as a
333  "normal" view, the other as an "exception" view.  This means that you can use
334  an exception as ``context`` for a normal view.
335
336Exception views can be configured with any view registration mechanism:
337``@view_config`` decorator or imperative ``add_view`` styles.
338
339.. note::
340
341   Pyramid's :term:`exception view` handling logic is implemented as a tween
342   factory function: :func:`pyramid.tweens.excview_tween_factory`.  If Pyramid
343   exception view handling is desired, and tween factories are specified via
344   the ``pyramid.tweens`` configuration setting, the
345   :func:`pyramid.tweens.excview_tween_factory` function must be added to the
346   ``pyramid.tweens`` configuration setting list explicitly.  If it is not
347   present, Pyramid will not perform exception view handling.
348
349.. index::
350   single: view http redirect
351   single: http redirect (from a view)
352
353.. _http_redirect:
354
355Using a View Callable to do an HTTP Redirect
356--------------------------------------------
357
358You can issue an HTTP redirect by using the
359:class:`pyramid.httpexceptions.HTTPFound` class.  Raising or returning an
360instance of this class will cause the client to receive a "302 Found" response.
361
362To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` instance.
363
364.. code-block:: python
365   :linenos:
366
367   from pyramid.httpexceptions import HTTPFound
368
369   def myview(request):
370       return HTTPFound(location='http://example.com')
371
372Alternately, you can *raise* an HTTPFound exception instead of returning one.
373
374.. code-block:: python
375   :linenos:
376
377   from pyramid.httpexceptions import HTTPFound
378
379   def myview(request):
380       raise HTTPFound(location='http://example.com')
381
382When the instance is raised, it is caught by the default :term:`exception
383response` handler and turned into a response.
384
385.. index::
386   single: unicode, views, and forms
387   single: forms, views, and unicode
388   single: views, forms, and unicode
389
390Handling Form Submissions in View Callables (Unicode and Character Set Issues)
391------------------------------------------------------------------------------
392
393Most web applications need to accept form submissions from web browsers and
394various other clients.  In :app:`Pyramid`, form submission handling logic is
395always part of a :term:`view`.  For a general overview of how to handle form
396submission data using the :term:`WebOb` API, see :ref:`webob_chapter` and
397`"Query and POST variables" within the WebOb documentation
398<http://docs.webob.org/en/latest/reference.html#query-post-variables>`_.
399:app:`Pyramid` defers to WebOb for its request and response implementations,
400and handling form submission data is a property of the request implementation.
401Understanding WebOb's request API is the key to understanding how to process
402form submission data.
403
404There are some defaults that you need to be aware of when trying to handle form
405submission data in a :app:`Pyramid` view.  Having high-order (i.e., non-ASCII)
406characters in data contained within form submissions is exceedingly common, and
407the UTF-8 encoding is the most common encoding used on the web for character
408data. Since Unicode values are much saner than working with and storing
409bytestrings, :app:`Pyramid` configures the :term:`WebOb` request machinery to
410attempt to decode form submission values into Unicode from UTF-8 implicitly.
411This implicit decoding happens when view code obtains form field values via the
412``request.params``, ``request.GET``, or ``request.POST`` APIs (see
413:ref:`request_module` for details about these APIs).
414
415.. note::
416
417   Many people find the difference between Unicode and UTF-8 confusing. Unicode
418   is a standard for representing text that supports most of the world's
419   writing systems. However, there are many ways that Unicode data can be
420   encoded into bytes for transit and storage. UTF-8 is a specific encoding for
421   Unicode that is backwards-compatible with ASCII. This makes UTF-8 very
422   convenient for encoding data where a large subset of that data is ASCII
423   characters, which is largely true on the web. UTF-8 is also the standard
424   character encoding for URLs.
425
426As an example, let's assume that the following form page is served up to a
427browser client, and its ``action`` points at some :app:`Pyramid` view code:
428
429.. code-block:: xml
430   :linenos:
431
432   <html xmlns="http://www.w3.org/1999/xhtml">
433     <head>
434       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
435     </head>
436     <form method="POST" action="myview">
437       <div>
438         <input type="text" name="firstname"/>
439       </div>
440       <div>
441         <input type="text" name="lastname"/>
442       </div>
443       <input type="submit" value="Submit"/>
444     </form>
445   </html>
446
447The ``myview`` view code in the :app:`Pyramid` application *must* expect that
448the values returned by ``request.params`` will be of type ``unicode``, as
449opposed to type ``str``. The following will work to accept a form post from the
450above form:
451
452.. code-block:: python
453   :linenos:
454
455   def myview(request):
456       firstname = request.params['firstname']
457       lastname = request.params['lastname']
458
459But the following ``myview`` view code *may not* work, as it tries to decode
460already-decoded (``unicode``) values obtained from ``request.params``:
461
462.. code-block:: python
463   :linenos:
464
465   def myview(request):
466       # the .decode('utf-8') will break below if there are any high-order
467       # characters in the firstname or lastname
468       firstname = request.params['firstname'].decode('utf-8')
469       lastname = request.params['lastname'].decode('utf-8')
470
471For implicit decoding to work reliably, you should ensure that every form you
472render that posts to a :app:`Pyramid` view explicitly defines a charset
473encoding of UTF-8. This can be done via a response that has a
474``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form above,
475with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within
476the HTML ``head`` of the page containing the form.  This must be done
477explicitly because all known browser clients assume that they should encode
478form data in the same character set implied by the ``Content-Type`` value of
479the response containing the form when subsequently submitting that form. There
480is no other generally accepted way to tell browser clients which charset to use
481to encode form data.  If you do not specify an encoding explicitly, the browser
482client will choose to encode form data in its default character set before
483submitting it, which may not be UTF-8 as the server expects.  If a request
484containing form data encoded in a non-UTF-8 ``charset`` is handled by your view
485code, eventually the request code accessed within your view will throw an error
486when it can't decode some high-order character encoded in another character set
487within form data, e.g., when ``request.params['somename']`` is accessed.
488
489If you are using the :class:`~pyramid.response.Response` class to generate a
490response, or if you use the ``render_template_*`` templating APIs, the UTF-8
491``charset`` is set automatically as the default via the ``Content-Type``
492header. If you return a ``Content-Type`` header without an explicit
493``charset``, a request will add a ``;charset=utf-8`` trailer to the
494``Content-Type`` header value for you for response content types that are
495textual (e.g., ``text/html`` or ``application/xml``) as it is rendered.  If you
496are using your own response object, you will need to ensure you do this
497yourself.
498
499.. note:: Only the *values* of request params obtained via ``request.params``,
500   ``request.GET`` or ``request.POST`` are decoded to Unicode objects
501   implicitly in the :app:`Pyramid` default configuration.  The keys are still
502   (byte) strings.
503
504
505.. index::
506   single: view calling convention
507
508.. _request_and_context_view_definitions:
509
510Alternate View Callable Argument/Calling Conventions
511----------------------------------------------------
512
513Usually view callables are defined to accept only a single argument:
514``request``.  However, view callables may alternately be defined as classes,
515functions, or any callable that accept *two* positional arguments: a
516:term:`context` resource as the first argument and a :term:`request` as the
517second argument.
518
519The :term:`context` and :term:`request` arguments passed to a view function
520defined in this style can be defined as follows:
521
522context
523  The :term:`resource` object found via tree :term:`traversal` or :term:`URL
524  dispatch`.
525
526request
527  A :app:`Pyramid` Request object representing the current WSGI request.
528
529The following types work as view callables in this style:
530
531#. Functions that accept two arguments: ``context`` and ``request``, e.g.:
532
533   .. code-block:: python
534       :linenos:
535
536       from pyramid.response import Response
537
538       def view(context, request):
539           return Response('OK')
540
541#. Classes that have an ``__init__`` method that accepts ``context, request``,
542   and a ``__call__`` method which accepts no arguments, e.g.:
543
544   .. code-block:: python
545      :linenos:
546
547      from pyramid.response import Response
548
549      class view(object):
550         def __init__(self, context, request):
551             self.context = context
552             self.request = request
553
554         def __call__(self):
555             return Response('OK')
556
557#. Arbitrary callables that have a ``__call__`` method that accepts ``context,
558   request``, e.g.:
559
560   .. code-block:: python
561      :linenos:
562
563      from pyramid.response import Response
564
565      class View(object):
566          def __call__(self, context, request):
567              return Response('OK')
568      view = View() # this is the view callable
569
570This style of calling convention is most useful for :term:`traversal` based
571applications, where the context object is frequently used within the view
572callable code itself.
573
574No matter which view calling convention is used, the view code always has
575access to the context via ``request.context``.
576
577.. index::
578   single: Passing in configuration variables
579
580.. _passing_in_config_variables:
581
582Passing Configuration Variables to a View
583-----------------------------------------
584
585For information on passing a variable from the configuration .ini files to a
586view, see :ref:`deployment_settings`.
587
588.. index::
589   single: Pylons-style controller dispatch
590
591Pylons-1.0-Style "Controller" Dispatch
592--------------------------------------
593
594A package named :term:`pyramid_handlers` (available from PyPI) provides an
595analogue of :term:`Pylons`-style "controllers", which are a special kind of
596view class which provides more automation when your application uses :term:`URL
597dispatch` solely.
598