Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

Changed overview and tutorial docs to use render_to_response and get_…

…object_or_404, to cut down on code

git-svn-id: bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b7528320b64f3e818f798daa7235f7b5721d4ac2 1 parent 3dcdce4
@adrianholovaty adrianholovaty authored
Showing with 62 additions and 40 deletions.
  1. +2 −13 docs/overview.txt
  2. +54 −7 docs/tutorial03.txt
  3. +6 −20 docs/tutorial04.txt
15 docs/overview.txt
@@ -195,20 +195,10 @@ Generally, a view retrieves data according to the parameters, loads a template
and renders the template with the retrieved data. Here's an example view for
article_detail from above::
- from import articles
def article_detail(request, year, month, article_id):
# Use the Django API to find an object matching the URL criteria.
- try:
- a = articles.get_object(pub_date__year=year, pub_date__month=month, pk=article_id)
- except articles.ArticleDoesNotExist:
- raise Http404
- t = template_loader.get_template('news/article_detail')
- c = Context(request, {
- 'article': a,
- })
- content = t.render(c)
- return HttpResponse(content)
+ a = get_object_or_404(articles, pub_date__year=year, pub_date__month=month, pk=article_id)
+ return render_to_response('news/article_detail', {'article': a})
This example uses Django's template system, which has several key features.
@@ -261,7 +251,6 @@ template has to define only what's unique to that template.
Here's what the "base" template might look like::
<title>{% block title %}{% endblock %}</title>
61 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
+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,
+ 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
+.. 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
26 docs/tutorial04.txt
@@ -48,27 +48,20 @@ included this line::
So let's create a ``vote()`` function in ``myproject/apps/polls/views/``::
- from django.core import template_loader
- from django.core.extensions import DjangoContext as Context
+ from django.core.extensions import get_object_or_404, render_to_response
from django.models.polls import choices, polls
- from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
- from django.core.exceptions import Http404
+ from django.utils.httpwrappers import HttpResponseRedirect
def vote(request, poll_id):
- try:
- p = polls.get_object(pk=poll_id)
- except polls.PollDoesNotExist:
- raise Http404
+ p = get_object_or_404(polls, pk=poll_id)
selected_choice = p.get_choice(pk=request.POST['choice'])
except (KeyError, choices.ChoiceDoesNotExist):
# Redisplay the poll voting form.
- t = template_loader.get_template('polls/detail')
- c = Context(request, {
+ return render_to_response('polls/detail', {
'poll': p,
'error_message': "You didn't select a choice.",
- return HttpResponse(t.render(c))
selected_choice.votes += 1
@@ -109,15 +102,8 @@ After somebody votes in a poll, the ``vote()`` view redirects to the results
page for the poll. Let's write that view::
def results(request, poll_id):
- try:
- p = polls.get_object(pk=poll_id)
- except polls.PollDoesNotExist:
- raise Http404
- t = template_loader.get_template('polls/results')
- c = Context(request, {
- 'poll': p,
- })
- return HttpResponse(t.render(c))
+ p = get_object_or_404(polls, pk=poll_id)
+ return render_to_response('polls/results', {'poll': p})
This is almost exactly the same as the ``detail()`` view from `Tutorial 3`_.
The only difference is the template name. We'll fix this redundancy later.

0 comments on commit b752832

Please sign in to comment.
Something went wrong with that request. Please try again.