parts/django/docs/topics/http/views.txt
changeset 307 c6bca38c1cbf
equal deleted inserted replaced
306:5ff1fc726848 307:c6bca38c1cbf
       
     1 =============
       
     2 Writing Views
       
     3 =============
       
     4 
       
     5 A view function, or *view* for short, is simply a Python function that takes a
       
     6 Web request and returns a Web response. This response can be the HTML contents
       
     7 of a Web page, or a redirect, or a 404 error, or an XML document, or an image .
       
     8 . . or anything, really. The view itself contains whatever arbitrary logic is
       
     9 necessary to return that response. This code can live anywhere you want, as long
       
    10 as it's on your Python path. There's no other requirement--no "magic," so to
       
    11 speak. For the sake of putting the code *somewhere*, let's create a file called
       
    12 ``views.py`` in the ``mysite`` directory, which you created in the previous
       
    13 chapter.
       
    14 
       
    15 A simple view
       
    16 =============
       
    17 
       
    18 Here's a view that returns the current date and time, as an HTML document:
       
    19 
       
    20 .. code-block:: python
       
    21 
       
    22     from django.http import HttpResponse
       
    23     import datetime
       
    24 
       
    25     def current_datetime(request):
       
    26         now = datetime.datetime.now()
       
    27         html = "<html><body>It is now %s.</body></html>" % now
       
    28         return HttpResponse(html)
       
    29 
       
    30 Let's step through this code one line at a time:
       
    31 
       
    32     * First, we import the class :class:`~django.http.HttpResponse` from the
       
    33       :mod:`django.http` module, along with Python's ``datetime`` library.
       
    34 
       
    35     * Next, we define a function called ``current_datetime``. This is the view
       
    36       function. Each view function takes an :class:`~django.http.HttpRequest`
       
    37       object as its first parameter, which is typically named ``request``.
       
    38 
       
    39       Note that the name of the view function doesn't matter; it doesn't have to
       
    40       be named in a certain way in order for Django to recognize it. We're
       
    41       calling it ``current_datetime`` here, because that name clearly indicates
       
    42       what it does.
       
    43 
       
    44     * The view returns an :class:`~django.http.HttpResponse` object that
       
    45       contains the generated response. Each view function is responsible for
       
    46       returning an :class:`~django.http.HttpResponse` object. (There are
       
    47       exceptions, but we'll get to those later.)
       
    48 
       
    49 .. admonition:: Django's Time Zone
       
    50     
       
    51     Django includes a ``TIME_ZONE`` setting that defaults to
       
    52     ``America/Chicago``. This probably isn't where you live, so you might want
       
    53     to change it in your settings file.
       
    54 
       
    55 Mapping URLs to Views
       
    56 =====================
       
    57 
       
    58 So, to recap, this view function returns an HTML page that includes the current
       
    59 date and time. To display this view at a particular URL, you'll need to create a
       
    60 *URLconf*; see :doc:`/topics/http/urls` for instructions.
       
    61 
       
    62 Returning errors
       
    63 ================
       
    64 
       
    65 Returning HTTP error codes in Django is easy. There are subclasses of
       
    66 :class:`~django.http.HttpResponse` for a number of common HTTP status codes
       
    67 other than 200 (which means *"OK"*). You can find the full list of available
       
    68 subclasses in the :ref:`request/response <ref-httpresponse-subclasses>`
       
    69 documentation.  Just return an instance of one of those subclasses instead of
       
    70 a normal :class:`~django.http.HttpResponse` in order to signify an error. For
       
    71 example::
       
    72 
       
    73     def my_view(request):
       
    74         # ...
       
    75         if foo:
       
    76             return HttpResponseNotFound('<h1>Page not found</h1>')
       
    77         else:
       
    78             return HttpResponse('<h1>Page was found</h1>')
       
    79 
       
    80 There isn't a specialized subclass for every possible HTTP response code,
       
    81 since many of them aren't going to be that common. However, as documented in
       
    82 the :class:`~django.http.HttpResponse` documentation, you can also pass the
       
    83 HTTP status code into the constructor for :class:`~django.http.HttpResponse`
       
    84 to create a return class for any status code you like. For example::
       
    85 
       
    86     def my_view(request):
       
    87         # ...
       
    88 
       
    89         # Return a "created" (201) response code.
       
    90         return HttpResponse(status=201)
       
    91 
       
    92 Because 404 errors are by far the most common HTTP error, there's an easier way
       
    93 to handle those errors.
       
    94 
       
    95 The Http404 exception
       
    96 ---------------------
       
    97 
       
    98 .. class:: django.http.Http404()
       
    99 
       
   100 When you return an error such as :class:`~django.http.HttpResponseNotFound`,
       
   101 you're responsible for defining the HTML of the resulting error page::
       
   102 
       
   103     return HttpResponseNotFound('<h1>Page not found</h1>')
       
   104 
       
   105 For convenience, and because it's a good idea to have a consistent 404 error page
       
   106 across your site, Django provides an ``Http404`` exception. If you raise
       
   107 ``Http404`` at any point in a view function, Django will catch it and return the
       
   108 standard error page for your application, along with an HTTP error code 404.
       
   109 
       
   110 Example usage::
       
   111 
       
   112     from django.http import Http404
       
   113 
       
   114     def detail(request, poll_id):
       
   115         try:
       
   116             p = Poll.objects.get(pk=poll_id)
       
   117         except Poll.DoesNotExist:
       
   118             raise Http404
       
   119         return render_to_response('polls/detail.html', {'poll': p})
       
   120 
       
   121 In order to use the ``Http404`` exception to its fullest, you should create a
       
   122 template that is displayed when a 404 error is raised. This template should be
       
   123 called ``404.html`` and located in the top level of your template tree.
       
   124 
       
   125 Customizing error views
       
   126 =======================
       
   127 
       
   128 The 404 (page not found) view
       
   129 -----------------------------
       
   130 
       
   131 When you raise an ``Http404`` exception, Django loads a special view devoted
       
   132 to handling 404 errors. By default, it's the view
       
   133 ``django.views.defaults.page_not_found``, which loads and renders the template
       
   134 ``404.html``.
       
   135 
       
   136 This means you need to define a ``404.html`` template in your root template
       
   137 directory. This template will be used for all 404 errors.
       
   138 
       
   139 This ``page_not_found`` view should suffice for 99% of Web applications, but if
       
   140 you want to override the 404 view, you can specify ``handler404`` in your
       
   141 URLconf, like so::
       
   142 
       
   143     handler404 = 'mysite.views.my_custom_404_view'
       
   144 
       
   145 Behind the scenes, Django determines the 404 view by looking for ``handler404``.
       
   146 By default, URLconfs contain the following line::
       
   147 
       
   148     from django.conf.urls.defaults import *
       
   149 
       
   150 That takes care of setting ``handler404`` in the current module. As you can see
       
   151 in ``django/conf/urls/defaults.py``, ``handler404`` is set to
       
   152 ``'django.views.defaults.page_not_found'`` by default.
       
   153 
       
   154 Three things to note about 404 views:
       
   155 
       
   156     * The 404 view is also called if Django doesn't find a match after checking
       
   157       every regular expression in the URLconf.
       
   158 
       
   159     * If you don't define your own 404 view -- and simply use the
       
   160       default, which is recommended -- you still have one obligation:
       
   161       you must create a ``404.html`` template in the root of your
       
   162       template directory. The default 404 view will use that template
       
   163       for all 404 errors. The default 404 view will pass one variable
       
   164       to the template: ``request_path``, which is the URL that resulted
       
   165       in the 404.
       
   166 
       
   167     * The 404 view is passed a :class:`~django.template.RequestContext` and
       
   168       will have access to variables supplied by your
       
   169       :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting (e.g.,
       
   170       :setting:`MEDIA_URL`).
       
   171 
       
   172     * If :setting:`DEBUG` is set to ``True`` (in your settings module), then
       
   173       your 404 view will never be used, and the traceback will be displayed
       
   174       instead.
       
   175 
       
   176 The 500 (server error) view
       
   177 ----------------------------
       
   178 
       
   179 Similarly, Django executes special-case behavior in the case of runtime errors
       
   180 in view code. If a view results in an exception, Django will, by default, call
       
   181 the view ``django.views.defaults.server_error``, which loads and renders the
       
   182 template ``500.html``.
       
   183 
       
   184 This means you need to define a ``500.html`` template in your root template
       
   185 directory. This template will be used for all server errors. The default 500
       
   186 view passes no variables to this template and is rendered with an empty
       
   187 ``Context`` to lessen the chance of additional errors.
       
   188 
       
   189 This ``server_error`` view should suffice for 99% of Web applications, but if
       
   190 you want to override the view, you can specify ``handler500`` in your
       
   191 URLconf, like so::
       
   192 
       
   193     handler500 = 'mysite.views.my_custom_error_view'
       
   194 
       
   195 Behind the scenes, Django determines the error view by looking for ``handler500``.
       
   196 By default, URLconfs contain the following line::
       
   197 
       
   198     from django.conf.urls.defaults import *
       
   199 
       
   200 That takes care of setting ``handler500`` in the current module. As you can see
       
   201 in ``django/conf/urls/defaults.py``, ``handler500`` is set to
       
   202 ``'django.views.defaults.server_error'`` by default.