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