Django templates define the layout and final formatting sent to end users after a view method is finished processing a request. In this chapter, you'll learn the syntax used by Django templates, the configuration options available for Django templates, as well as the various Django template constructs (e.g. filters, tags, context processors) that allow you to create elaborate layouts and apply formatting to the content presented to end users.
Django template syntax
Although there are over one hundred built-in constructs that help you build Django templates -- all of which you'll learn as this chapter progresses -- to start out, these are the most important syntax elements you need to recognize:
{{output_variable}}
.- Values surrounded by double curly braces at the start and end represent output for variables. Variables are passed by Django views, url options or context processors into templates. In a template, you can use{{}}
to output the contents of a variable, as well as use Python's dot notation to output deeper elements of a variable (e.g. fields, keys, methods). For example,{{store.name}}
tells a Django template to output thestore
variable'sname
, wherestore
can be anobject
andname
a field orstore
can be a dictionary andname
a key.{% tag %}
.- Values surrounded by curly braces wrapped with percentage signs are called tags. Django tags offer complex formatting logic wrapped in a simple syntax representation.variable|filter
.-Values declared after a vertical bar|
are called filters. Django filters offer a way to apply formatting logic to individual variables.
Any other syntax in Django
templates besides these three variations is treated 'as is'. This
means that if a template declares the Hypertext Markup
Language (HTML) heading <h1>Welcome!</h1>
,
a user will get a large HTML heading. It's that simple.
But let's take a look at one not so obvious Django template syntax behavior that's important you understand right away, since it's a recurring theme in practically everything associated with Django templates.
Auto-escaping: HTML and erring on the safe side
Django projects operate on the web, so by default all templates are assumed to produce HTML. While this is a reasonable assumption, it isn't, until you face one of two things:
- You can't ensure Django templates produce valid HTML and in fact may produce dangerous markup.
- You want Django templates to produce non-HTML content, such as Comma Separated Values (CSV), eXtensible Markup Language (XML) or JavaScript Object Notation (JSON).
So how could you possibly introduce invalid HTML or even dangerous content into Django templates ? Well it's the Internet, it's content from other users or providers that can end up in your Django templates that can cause problems (e.g. data submitted by users, third party services, content from databases).
The issue isn't content you place directly in Django templates -- that's given to be valid since you type it in -- the issue is dynamic content placed through variables, tags, filters and context processors, which has the potential to come from anywhere. Let's analyze this further with the following variables:
store_legend = "<b>Open since 1965!</b>" js_user_date = "<script>var user_date = new Date()</script>"
If variables with this content
make it to Django templates and you attempt to output them, they
are output verbatim. The store_legend
won't
be output as an HTML bold statement, but rather a statement
surrounded by <b>
and </b>
.
Similarly, the js_user_date
won't produce a JavaScript
variable with a user browser local date, but rather output the
<script>
statement literally.
This happens because by default Django auto-escapes content present in dynamic constructs (i.e. variables, tags, filters and context processors). Table 3-1 illustrates the characters Django auto-escapes by default.
Table 3-1. Characters Django auto-escapes by default
Original character | Escaped to |
---|---|
< | < |
> | > |
'(single quote) | ' |
" (double quote) | " |
& | & |
As you can see in table 3-1, Django auto-escaping consists of converting potentially conflicting and even dangerous characters -- in the context of HTML -- to equivalent visual representations also known as escape characters[1].
This is done because malicious users or unchecked sources can easily produce content with the characters on the left column of table 3-1, that can mangle a user interface or execute malicious JavaScript code. So Django errs on the safe side and auto-escapes the characters in table 3-1 to equivalent visual representations. While you can certainly disable the auto-escaping of characters from table 3-1, this has to be done explicitly, since it represents a security risk.
While auto-escaping is a good
security precaution for HTML output, this takes us to the second
point in assuming Django always produces HTML. What happens if a
Django template has to output CSV, JSON or XML content,where
characters like <
, >
,
'
(single quote), "
(double quote) and
&
, have special meaning to content consumers and
can't use equivalent visual representations ? In such cases, you'll
also to need to explicitly disable the default auto-escaping
behavior enforced by Django.
So whether you want to output actual HTML through variables in Django templates or output CSV, JSON or XML without Django applying an HTML security practice to this content, you'll need to deal with Django auto-escaping.
There are various ways to control auto-escaping in Django templates (e.g. globally, individual variables, individual filters) which you'll learn as you progress through this chapter. But auto-escaping is a constant theme in Django templates, along with these related terms:
- Safe.- If a Django template construct is marked as safe, it means no characters from table 3-1 are escaped. In other words, safe equals "I know what I'm doing" output the content 'as is'.
- Escape.- If a Django template construct is marked to be escaped, it means characters from table 3-1 are escaped. In other words, escape equals "Ensure no potentially dangerous HTML characters are output, use equivalent visual representations".
- Auto-escape on/ Auto-escape off (safe).- If a Django template uses auto-escape on, it means Django template constructs in this scope should escape characters from table 3-1. If a Django template uses auto-escape off, it means Django template constructs in this scope should be output 'as is' and not escape characters from table 3-1.
And with this we finish the conversation on this rather dry yet important topic of Django auto-escaping. Next, let's explore the various configuration options for Django templates.