diff options
Diffstat (limited to 'docs/tutorial03.txt')
| -rw-r--r-- | docs/tutorial03.txt | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt index 875bd7b86a..d34c480661 100644 --- a/docs/tutorial03.txt +++ b/docs/tutorial03.txt @@ -192,14 +192,14 @@ you want to change the way the page looks, you'll have to edit this Python code. So let's use Django's template system to separate the design from Python:: from django.core import template_loader - from django.core.extensions import DjangoContext as Context + from django.core.template import Context from django.models.polls import polls from django.utils.httpwrappers import HttpResponse def index(request): latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5) t = template_loader.get_template('polls/index') - c = Context(request, { + c = Context({ 'latest_poll_list': latest_poll_list, }) return HttpResponse(t.render(c)) @@ -242,6 +242,27 @@ Put the following code in that template:: Load the page in your Web browser, and you should see a bulleted-list containing the "What's up" poll from Tutorial 1. +A shortcut: render_to_response() +-------------------------------- + +It's a very common idiom to load a template, fill a context and return an +``HttpResponse`` object with the result of the rendered template. Django +provides a shortcut. Here's the full ``index()`` view, rewritten:: + + from django.core.extensions import render_to_response + from django.models.polls import polls + + def index(request): + latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5) + return render_to_response('polls/index', {'latest_poll_list': latest_poll_list}) + +Note that we no longer need to import ``template_loader``, ``Context`` or +``HttpResponse``. + +The ``render_to_response()`` function takes a template name as its first +argument and a dictionary as its optional second argument. It returns an +``HttpResponse`` object of the given template rendered with the given context. + Raising 404 =========== @@ -254,15 +275,41 @@ for a given poll. Here's the view:: p = polls.get_object(pk=poll_id) except polls.PollDoesNotExist: raise Http404 - t = template_loader.get_template('polls/detail') - c = Context(request, { - 'poll': p, - }) - return HttpResponse(t.render(c)) + return render_to_response('polls/detail', {'poll': p}) The new concept here: The view raises the ``django.core.exceptions.Http404`` exception if a poll with the requested ID doesn't exist. +A shortcut: get_object_or_404() +------------------------------- + +It's a very common idiom to use ``get_object()`` and raise ``Http404`` if the +object doesn't exist. Django provides a shortcut. Here's the ``detail()`` view, +rewritten: + + from django.core.extensions import get_object_or_404 + def detail(request, poll_id): + p = get_object_or_404(polls, pk=poll_id) + return render_to_response('polls/detail', {'poll': p}) + +The ``get_object_or_404()`` function takes a Django model module as its first +argument and an arbitrary number of keyword arguments, which it passes to the +module's ``get_object()`` function. It raises ``Http404`` if the object doesn't +exist. + +.. admonition:: Philosophy + + Why do we use a helper function ``get_object_or_404()`` instead of + automatically catching the ``*DoesNotExist`` exceptions at a higher level, + or having the model API raise ``Http404`` instead of ``*DoesNotExist``? + + Because that would couple the model layer to the view layer. One of the + foremost design goals of Django is to maintain loose coupling. + +There's also a ``get_list_or_404()`` function, which works just as +``get_object_or_404()`` -- except using ``get_list()`` instead of +``get_object()``. It raises ``Http404`` if the list is empty. + Write a 404 (page not found) view ================================= |
