The document discusses Django's template inheritance system. It introduces a base template that defines common elements like the page header and footer. This base template uses block tags to denote sections that child templates can override. Two child templates are shown that extend the base template and override its title and content blocks to customize each page while maintaining a common layout. Template inheritance allows avoiding redundancy and making site-wide changes by modifying only the base template.
1. The
Django
Book
Chapter
4:
Templates
(Supplement)
Speaker:
Vincent
Chien
2. render_to_response
Django Book Documentation, Release 0.1
5.6.1 render_to_response()
We’ve shown you how to load a template, fill a Context and return an HttpResponse object with the result of
the rendered template. We’ve optimized it to use get_template() instead of hard-coding templates and template
paths. But it still requires a fair amount of typing to do those things. Because this is such a common idiom, Django
provides a shortcut that lets you load a template, render it and return an HttpResponse – all in one line of code.
This shortcut is a function called render_to_response(), which lives in the module django.shortcuts.
Most of the time, you’ll be using render_to_response() rather than loading templates and creating Context
and HttpResponse objects manually – unless your employer judges your work by total lines of code written, that
is.
Here’s the ongoing current_datetime example rewritten to use render_to_response():
from django.shortcuts import render_to_response
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response(’current_datetime.html’, {’current_date’: now})
What a difference! Let’s step through the code changes:
• We no longer have to import get_template, Template, Context, or HttpResponse. Instead, we
import django.shortcuts.render_to_response. The import datetime remains.
• Within the current_datetime function, we still calculate now, but the template loading, context creation,
(os.path.dirname), then joins that with templates in a cross-platform way (os.path.join), then
ensures that everything uses forward slashes instead of backslashes (in case of Windows).
While we’re on the topic of dynamic Python code in settings files, we should point out that it’s very important to
avoid Python errors in your settings file. If you introduce a syntax error, or a runtime error, your Django-powered
site will likely crash.
With TEMPLATE_DIRS set, the next step is to change the view code to use Django’s template-loading functionality
rather than hard-coding the template paths. Returning to our current_datetime view, let’s change it like so:
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
t = get_template(’current_datetime.html’)
html = t.render(Context({’current_date’: now}))
return HttpResponse(html)
50 Chapter 5. Chapter 4: Templates
Before
A<er
3. The
local()
Trick
The first argument to render_to_response() is the name of the template to use. The second argument, if given,
should be a dictionary to use in creating a Context for that template. If you don’t provide a second argument,
render_to_response() will use an empty dictionary.
5.6.2 The locals() Trick
Consider our latest incarnation of current_datetime:
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response(’current_datetime.html’, {’current_date’: now})
Many times, as in this example, you’ll find yourself calculating some values, storing them in variables (e.g., now in
the preceding code), and sending those variables to the template. Particularly lazy programmers should note that it’s
slightly redundant to have to give names for temporary variables and give names for the template variables. Not only
is it redundant, but also it’s extra typing.
So if you’re one of those lazy programmers and you like keeping code particularly concise, you can take advantage of
a built-in Python function called locals(). It returns a dictionary mapping all local variable names to their values,
where “local” means all variables that have been defined within the current scope. Thus, the preceding view could be
rewritten like so:
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response(’current_datetime.html’, locals())
Here, instead of manually specifying the context dictionary as before, we pass the value of locals(), which will
include all variables defined at that point in the function’s execution. As a consequence, we’ve renamed the now
52 Chapter 5. Chapter 4: Templates
Consider our latest incarnation of current_datetime:
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response(’current_datetime.html’, {’current_date’: now})
Many times, as in this example, you’ll find yourself calculating some values, storing them in variables (e.g., now
the preceding code), and sending those variables to the template. Particularly lazy programmers should note that i
slightly redundant to have to give names for temporary variables and give names for the template variables. Not on
is it redundant, but also it’s extra typing.
So if you’re one of those lazy programmers and you like keeping code particularly concise, you can take advantage
a built-in Python function called locals(). It returns a dictionary mapping all local variable names to their valu
where “local” means all variables that have been defined within the current scope. Thus, the preceding view could
rewritten like so:
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response(’current_datetime.html’, locals())
Here, instead of manually specifying the context dictionary as before, we pass the value of locals(), which w
include all variables defined at that point in the function’s execution. As a consequence, we’ve renamed the n
52 Chapter 5. Chapter 4: Templat
Before
A<er
4. HTML
Classic
Way
Django Book Documentation, Release 0.1
# mypage.html
<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>
# includes/nav.html
<div id="nav">
You are in: {{ current_section }}
</div>
If you render mypage.html with a context containing current_section, then
the “included” template, as you would expect.
5. Template
Inheritance
With an include-based strategy, headers and footers are easy. It’s the middle ground that’s messy. In this example, both
pages feature a title – <h1>My helpful timestamp site</h1> – but that title can’t fit into header.html
because the <title> on both pages is different. If we included the <h1> in the header, we’d have to include the
<title>, which wouldn’t allow us to customize it per page. See where this is going?
Django’s template inheritance system solves these problems. You can think of it as an “inside-out” version of server-
side includes. Instead of defining the snippets that are common, you define the snippets that are different.
The first step is to define a base template – a skeleton of your page that child templates will later fill in. Here’s a base
template for our ongoing example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>
This template, which we’ll call base.html, defines a simple HTML skeleton document that we’ll use for all the
pages on the site. It’s the job of child templates to override, or add to, or leave alone the contents of the blocks. (If
5.7. Template Inheritance 55
Django Book Documentation, Release 0.1
you’re following along, save this file to your template directory as base.html.)
We’re using a template tag here that you haven’t seen before: the {% block %} tag. All the {% block %} tags
do is tell the template engine that a child template may override those portions of the template.
Now that we have this base template, we can modify our existing current_datetime.html template to use it:
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
While we’re at it, let’s create a template for the hours_ahead view from Chapter 3. (If you’re following along with
code, we’ll leave it up to you to change hours_ahead to use the template system instead of hard-coded HTML.)
Here’s what that could look like:
{% extends "base.html" %}
Base.html
Child
A
Django Book Documentation, Release 0.1
you’re following along, save this file to your template directory as base.html.)
We’re using a template tag here that you haven’t seen before: the {% block %} tag. All the {% b
do is tell the template engine that a child template may override those portions of the template.
Now that we have this base template, we can modify our existing current_datetime.html tem
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
While we’re at it, let’s create a template for the hours_ahead view from Chapter 3. (If you’re follo
code, we’ll leave it up to you to change hours_ahead to use the template system instead of hard
Here’s what that could look like:
{% extends "base.html" %}
{% block title %}Future time{% endblock %}
{% block content %}
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock %}
Isn’t this beautiful? Each template contains only the code that’s unique to that template. No redund
you need to make a site-wide design change, just make the change to base.html, and all of the othe
immediately reflect the change.
Here’s how it works. When you load the template current_datetime.html, the template eng
Child
B