Django template system

Django template system

Official documents

Common grammar

Only two special symbols need to be remembered:

{{   }} And {%%}

Use {}} for variable related and {%%} for logic related.


In Django's template language, use this syntax: {variable name}}.

When the template engine encounters a variable, it will evaluate the variable and replace it with the result. The name of the variable includes any combination of alphanumeric and underscore (""). There can be no spaces or punctuation in the variable name.

Points (.) have special meanings in the template language. When the template system encounters points (".), it will query in this order:

Dictionary lookup
Attribute or method lookup
Numeric index lookup

matters needing attention:

  1. If the value of the calculation result is callable, it will be called without parameters. The result of the call will become the value of the template.
  2. If the variable used does not exist, the template system will insert the value of string_if_invalid option, which is set to '' (empty string) by default.

Several examples:

Code in view:

def template_test(request):
    l = [11, 22, 33]
    d = {"name": "alex"}

    class Person(object):
        def __init__(self, name, age):
   = name
            self.age = age

        def dream(self):
            return "{} is dream...".format(

    Alex = Person(name="Alex", age=34)
    jason = Person(name="jason", age=9000)
    Eva_J = Person(name="Eva_J", age=18)

    person_list = [Alex, jason, Eva_J]
    return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

Supported writing methods in template:

{# take l First parameter in #}
{{ l.0 }}
{# In the dictionary key Value of #}
{{ }}
{# Fetch object name attribute #}
{{ }}
{# .The operation can only call methods without parameters #}
{{ person_list.0.dream }}


In Django's template language, the display of variables is changed by using filters.

Syntax of filter: {{value|filter_name: parameter}}

Use the pipe symbol "|" to apply the filter.

For example: {{name|lower}} will apply the name variable to the lower filter before displaying its value. The function of lower here is to make all text lowercase.

matters needing attention:

  1. Filters support "chain" operation, that is, the output of one filter is used as the input of another filter.
  2. The filter can accept parameters, such as: {{sss|truncatewords:30}}, which will display the first 30 words of sss.
  3. If the filter parameter contains spaces, it must be enclosed in quotation marks. For example, use commas and spaces to connect elements in a list, such as: {list|join: ','}}
  4. There is no space around '|' no space, no space, no space


Django's template language provides about 60 built-in filters.


If a variable is false or empty, use the given default value. Otherwise, use the value of the variable.

{{ value|default:"nothing"}}

If value is not passed or the value is empty, nothing will be displayed


The length of the return value, applied to strings and lists.

{{ value|length }}

Return the length of value, such as value=['a ',  ' b',  ' c',  ' d '], it shows 4


Format the value to a "human readable" file size (for example  ' 13 KB',  ' 4.1 MB',  ' 102 bytes', etc.)

{{ value|filesizeformat }}

If value is 123456789, the output will be 117.7 MB.






{{ value|date:"Y-m-d H:i:s"}}

  Available parameters:

Format characterdescribeSample output
a 'a.m.' or 'p.m.' (note that this is slightly different from the output of PHP because it includes periods that conform to the Associated Press style) 'a.m.'
A 'AM' or 'PM'. 'AM'
b Month, text, 3 letters, lowercase. 'jan'
B Not implemented.  
c ISO 8601 format. (Note: unlike other formatters, such as "Z", "O" or "r", if the value is naive datetime, the "c" formatter does not add a time zone offset (see) datetime.tzinfo) . 2008-01-02T10:30:00.000123+02:00 or 2008-01-02T10:30:00.000123 if datetime is naive
d The day of the month, a 2-digit number with leading zeros. '01' to '31'
D Text of the week, 3 letters. "Friday"
e The time zone name may be in any format, or it may return an empty string, depending on datetime. '', 'GMT', '500', 'US/Eastern', etc
E Month, an alternative representation of a specific region, is usually used for long date representation. 'listopada' (not 'Listopad' for Polish regions)
f Time, in hours and minutes of 12 hours, if they are zero, then minutes stay. Proprietary extension. '1','1:30'
F Month, Wen, Chang. 'January'
g Hour, 12 hour format, no leading zeros. '1' to '12'
G Hour, 24-hour format, no leading zeros. '0' to '23'
h Hour, 12 hour format. '01' to '12'
H Hour, 24-hour format. '00' to '23'
i minute. '00' to '59'
I Daylight saving time, whether effective or not. '1' or '0'
j Days of months without leading zeros. '1' to '31'
l The day of the week is long. 'Friday'
L Boolean whether it is a leap year. True or False
m Month, 2 digits with leading zeros. '01' to '12'
M Month, text, 3 letters. "Yang"
n Month has no leading zero. '1' to '12'
N Associated press style month abbreviation. Proprietary extension. 'Jan.','Feb.','March','May'
o ISO-8601 week number, corresponding to the number of ISO-8601 weeks (W) using leap years. For more common year formats, see Y. '1999'
O The difference from Greenwich mean time is in a few hours. '+0200'
P The time is 12 hours, minutes and 'a.m.' /'p.m. 'if it is zero, the minutes stay, and the strings "Midnight" and "noon" in special cases. Proprietary extension. '1 am','1:30 pm' / t3>,'midnight','noon','12: 30 pm' / T10>
r RFC 5322 Format date. 'Thu, 21 Dec 2000 16:01:07 +0200'
s Second, a 2-digit number with leading zeros. '00' to '59'
S One month English ordinal suffix, 2 characters. 'st ',' nd ',' rd 'or' th '
t The number of days in a given month. 28 to 31
T The time zone of this machine. 'EST','MDT'
u Microseconds. 000000 to 999999
U Half since Unix Epoch (00:00:00 UTC, January 1, 1970).  
w The day of the week, the number has no leading zero. '0' (Sunday) to '6' (Saturday)
W ISO-8601 number of weeks, starting on Monday. 1,53
y Year, 2 digits. '99'
Y Year, 4 digits. '1999'
z Days of the year 0 to 365
Z Time zone offset, in seconds. The offset of the time zone west of UTC is always negative, and they are always positive for the time zone east of UTC. -43200 to 43200



Django's template will automatically escape HTML tags, JS and other syntax tags. The reason is obvious. This is for security. However, sometimes we may not want these HTML elements to be escaped. For example, when we build a content management system, the articles added in the background are modified. These modifications may be annotated with HTML modifications through an editor similar to fckeeditor If the text of the modifier is automatically escaped, it will display the source file of the HTML tag. There are two ways to turn off the automatic escape of HTML in Django. If it is a separate variable, we can tell Django that this code is safe without escape through the filter "|safe".

For example:

Value = "a href = '#' > Click me < / a >"

{{ value|safe}}


If the string characters are more than the specified number of characters, it will be truncated. The truncated string will end with a translatable ellipsis sequence (...).

Parameter: number of truncated characters

{{ value|truncatechars:9}}


Truncate the string after a certain number of words.

{{ value|truncatewords:9}}


Remove all strings in value that are the same as the given variable

{{ value|cut:' ' }}

If value is' i love you ', then' iloveyou 'will be output


Connect lists using strings, such as Python's str.join(list)


Format the date as the time from that date (for example, "4 days, 6 hours").

Takes an optional parameter, which is a variable containing the date used as the comparison point (without parameters, the comparison point is now). For example, if you blog_date is a date instance representing midnight on June 1, 2006, and comment_date is the date instance of 08:00 on June 1, 2006, then the following will return "8 hours":

{{ blog_date|timesince:comment_date }}

Minutes is the smallest unit used, and "0 minutes" will be returned for any future date relative to the comparison point.


Similar to timing, except that it measures the time from now until a given date or date time. For example, if today is June 1, 2006, and Conference_ If date is the date instance of June 29, 2006, then {{conference_date | timeuntil}} will return "4 weeks".

Use an optional parameter, which is a variable that contains the date (not the present) used as the comparison point. If from_ If the date contains June 22, 2006, the following will return "1 week":

{{ conference_date|timeuntil:from_date }}

Custom filter

Custom filters are simply Python functions with one or two arguments:

  • Value of variable (input) -- not necessarily a string
  • Parameter value - this can have a default value or be omitted completely

For example, in the filter {{var | foo:'bar'}}, the filter foo will pass the variable VaR and the parameter "bar".


Custom filter code file placement:

    templatetags/  # Create a new package under app01  # Create a file to store the custom filter

Write custom filter

from django import template
register = template.Library()

def cut(value, arg):
    return value.replace(arg, "")

def add_sb(value):
    return "{} SB".format(value)

Use custom filter

{# First import our custom filter That document #}
{% load app01_filters %}

{# Use our custom filter #}
{{ somevariable|cut:"0" }}
{{|addSB }}


for loop

Normal for loop

{% for user in user_list %}
    <li>{{ }}</li>
{% endfor %}

Some parameters available for the for loop:


forloop.counter Index value of the current loop (starting from 1)
forloop.counter0 Index value of the current loop (starting from 0)
forloop.revcounter Reverse index value of the current cycle (starting from 1)
forloop.revcounter0 Reverse index value of the current loop (starting from 0)
forloop.first Is the current loop the first loop (Boolean)
forloop.last Is the current loop the last loop (Boolean)
forloop.parentloop Outer circulation of this layer

for ... empty

{% for user in user_list %}
    <li>{{ }}</li>
{% empty %}
    <li>absolutely empty</li>
{% endfor %}

if judgment

if,elif and else

{% if user_list %}
  Number of users:{{ user_list|length }}
{% elif black_list %}
  Number of blacklists:{{ black_list|length }}
{% else %}
  No users
{% endif %}

Of course, you can only have if and else

{% if user_list|length > 5 %}
  Seven seat luxury SUV
{% else %}
{% endif %}

if statements support and, or, = =, >, <,! =, < =, > = In, not in, is, is not judgment.


Define an intermediate variable, which is mostly used to alias a complex variable.

Be careful not to add spaces around the equal sign.

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}


{% with business.employees.count as total %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}



This tag is used for Cross Site Request Forgery protection.

Write {% csrf_token%}


{# ... #}

matters needing attention

1. Django's template language does not support continuous judgment, that is, the following writing methods are not supported:

{% if a > b > c %}
{% endif %}


2. In Django's template language, the priority of attributes is greater than that of methods

def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})

As mentioned above, when we render a page using the render method, a key in the dictionary D is items and there is a default d.items() method. At this time, in the template language:

{{ data.items }}

By default, the value of d's items key will be taken.


<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  {% block page-css %}
  {% endblock %}

<h1>This is the title of the motherboard</h1>

{% block page-main %}

{% endblock %}
<h1>Motherboard bottom content</h1>
{% block page-js %}

{% endblock %}

Note: we usually define page specific CSS blocks and JS blocks in the motherboard to facilitate sub page replacement.

Inherit motherboard

In the sub page, use the following syntax at the top of the page to inherit the motherboard.

{% extends 'layouts.html' %}


By using {% block in the motherboard   xxx%} to define the "block".

In the sub page, the corresponding content in the motherboard is replaced by defining the block name in the motherboard.

{% block page-main %}
  <p>The world is thin</p>
  <p>Human evil</p>
  <p>Rain sends evening flowers to fall</p>
{% endblock %}


Common page contents such as navigation bar, footer information and other components can be saved in a separate file, and then imported according to the following syntax where necessary.

{% include 'navbar.html' %}

Static file related

{% static %}

{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

Use when referencing JS files:

{% load static %}
<script src="{% static "mytest.js" %}"></script>

A file can be saved as a variable if it is used in many places

{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

{% get_static_prefix %}

{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />


{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />


Similar to a custom filter, it only receives more flexible parameters.

Define and register simple tag

def plus(a, b, c):
    return "{} + {} + {}".format(a, b, c)

Use custom simple tag

{% load app01_demo %}

{# simple tag #}
{% plus "1" "2" "abc" %}


Mostly used to return html code fragments



from django import template

register = template.Library()

def show_results(n):
    n = 1 if n < 1 else int(n)
    data = ["The first{}term".format(i) for i in range(1, n+1)]
    return {"data": data}


  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}


<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>inclusion_tag test</title>

{% load inclusion_tag_test %}

{% show_results 10 %}


Posted by ben.hornshaw on Tue, 23 Nov 2021 23:43:47 -0800