OverIQ.com

Template filters in Django

Last updated on July 27, 2020


Django filters are used to modify the value of the variable before they are rendered as HTML code. To use a filter, type pipe character (|) followed by the filter name after the variable name.

{{ variable|filter_name }}

lower filter #

The lower filter, when applied to a variable, converts all the uppercase characters in the variable to lowercase equivalent. For example:

<p>{{ name|lower }}</p>

If the value of the name variable is "Tom Sawyer" then the above code would produce the following HTML.

<p>tom sawyer</p>

upper filter #

The upper filter is exactly the opposite of lower filter. It converts all the characters in the variable to uppercase equivalent. For example:

<p>{{ name|upper }}</p>

If the value of the name variable is "tom sawyer" then the above code would produce the following HTML.

<p>TOM SAWYER</p>

capfirst filter #

The capfirst filter converts only the first character in the variable to it's uppercase equivalent. For example:

<p>{{ name|capfirst }}</p>

If variable name contains "tom sawyer" then the above code would produce the following HTML.

<p>Tom sawyer</p>

You can also chain filters. For example:

<p>{{ name|lower|capfirst }}</p>

Here the name variable is first converted to lower case characters then the capfirst filter is applied on the result.

title filter #

The title filter capitalizes the first letter of every word. For example:

<p>{{ name|title }}</p>

If variable name contains "tom sawyer" then the above code would produce the following HTML.

<p>Tom Sawyer</p>

length filter #

The length filter determines the length of the value. It works with string, list, dictionary, and tuples. For example:

<p>The length variable name is {{ name|length }}</p>

If variable name contains "tom sawyer" then the above code would produce the following HTML.

<p>The length variable name is 10</p>

truncatewords filter #

The truncatewords filter truncates (shorten) a string after a certain number of words. After truncating string it appends ... (known as an ellipsis) to the end of the truncated string. The truncatewords is one of those filters to which you can pass an argument. To pass an argument to a filter type colon (:) followed by the argument inside double quotes (""). To pass multiple arguments to a filter separate them using a comma (,). The truncatewords accepts a single argument, which indicates the number words to truncate after. For example, to output only the first 10 words of a blog post do this:

<p>{{ post|truncatewords:"10" }}</p>

If post variable is defined as:

post = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu lectus ut lacus posuere fringilla id eu turpis."

The above code will produce the following HTML.

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu ...</p>

truncatechars filter #

The truncatechars filter is similar to truncatewords but instead of truncating by words it truncates by characters. It truncates a string if it is larger than the specified number of characters. Just like truncatewords filter, after truncating string truncatechars filter appends ... (ellipsis) to the truncated string. For example:

{{ long_text|truncatechars:"10" }}

This will truncate the string and appends ... to the end if it is larger than 10 characters.

If long_text contains "Lorem ipsum dolor sit amet, consectetur adipiscing elit" then the above code will produce the following HTML.

<p>Lorem i...</p>

pluralize filter #

The pluralize filter is used to handle suffixes. Lets take an example:

<p>You have {{ num }} products in your cart</p>

If n is 1 then we would like to display.

<p>You have 1 product in your cart</p>

On the other and if n is 10 then we would like to display.

<p>You have 10 products in your cart</p>

Notice the s in the string products.

We can use pluralize filter to handle these conditions easily.

<p>You have {{ num }} product{{ num|pluralize }} in your cart</p>

Now, if num is 1 the output will be:

<p>You have 1 product in your cart</p>

If the value if num is 100, then the output will be:

<p>You have 100 products in your cart</p>

By default pluralize filter appends "s" to the string. However, not all plural words ends with "s", some also end with "es" like tomatoes. For example:

<p>I have {{ num }} tomato{{ num|pluralize }}</p>

If num equals to 5 then the above code will output:

<p>I have 5 tomatos</p>

Certainly, this is wrong. To provide an alternative suffix you can pass a parameter to the pluralize filter. For example:

<p>I have {{ num }} tomato{{ num|pluralize:"es" }}</p>

If num equals to 5 the output will be:

<p>I have 5 tomatoes</p>

There are still some words which don't pluralize by a simple suffix like diary and diaries, cherry and cherries etc. To handle such special cases you have to provide both singular and plural suffixes as parameters to the pluralize filter. For example:

<p>I have {{ num }} diar{{ num|pluralize:"y,ies" }}</p>

If the num is 1 output will be:

<p>I have 1 diary</p>

If the num is 5 output will be:

<p>I have 5 diaries</p>

date filter #

We use date filter to format datetime.date and datetime.datetime objects. The date filter uses some special format characters to format datetime.date and datetime.datetime objects. To format a date pass a string of format characters as a parameter to the date filter. For example, let's say our context has a datetime.datetime object named now defined as:

now = datetime.datetime.now()

And our template contains the following code:

<p>Today is {{ now }}</p>

If we don't use the date filter, then the above code would produce the following HTML.

<p>Today is Jan. 27, 2017, 4:28 p.m.</p>

The following are some commonly used format strings available for you to use with the date filter:

Character What it does? Example
d Prints day of the month using 2 digit numbers 01 to 31
D Prints day of the week using three letter Mon for Monday, Tue for Tuesday and so on
m Prints month using 2 digits numbers 01 for January, 02 for February and so on
M Prints month using three letters numbers Jan for January, Feb for February and so on
i Prints minutes 00 to 59
h Prints hours in 12-hour format 01 to 12
H Prints hours in 24-hour format 00 to 23
s Prints seconds 00 to 59
a Prints "a.m." or "p.m." a.m., p.m.
Y Prints year using full 4 digits 2001, 2014 and so on

Lets add some format character to the date filter as follows:

<p>Today is {{ now|date:"D d M Y" }}</p>

This will output something like this:

<p>Today is Fri 27 Jan 2017</p>

linebreaks filter #

The linebreaks filter converts line breaks in strings to appropriate HTML. If a string has newline it will be converted to <br/> and newline followed by a blank line will be converted to </p>.

{{ text|linebreak }}

Consider the following examples:

Example 1:

1
2
3
4
content = '''\
this is
a content
'''
{{ content|linebreaks }}

Then the output will be:

<p>this is<br />a test<br /></p>

In the variable content there are two newline characters, the first one appears after the word is (line 2) and the second one appears after the word content (line 3). The
linebreaks filter replaces these newline characters with a <br /> tag and wraps the entire string in the <p> tag.

Example 2:

1
2
3
4
5
content = '''\
this is

a test
'''
{{ content|linebreaks }}

Then the output will be:

1
2
3
<p>this is</p>

<p>a test<br /></p>

linebreaksbr filter #

The linebreaksbr filter only converts newline in strings to <br> tag. For example:

{{ text|linebreaksbr}}

Now if the value of text variable is "Filter string\n using linebreaksbr" the output will be :

Filter string<br /> using linebreaksbr

autoescape tag #

Because of security concerns, Django template system automatically does the escaping for you. Consider the following example:

Suppose variable my_code contains "<p>this is short para </p>" and the code in the template is:

{{ my_code }}

The above code would be rendered as the following HTML:

&lt;p&gt;THIS IS TEST&lt;/p&gt;

There are two ways to turn off escaping:

  1. safe filter.
  2. autoescape filter.

safe filter #

{{ my_code|safe }}

This code would produce the following HTML output:

<p>this is short para </p>

The safe filter tells Django Template system that my_code variable is safe does not require escaping.

Another way to turn off escaping is to use autoescape tag

autoescape tag #

The autoescape tag lets you escape/unescape big chunks of content within the template. It accepts either on or off as an argument, which indicates whether auto-escaping is in effect within the block or not.

For example:

1
2
3
{% autoescape on %}
    {{ code_snippet }}
{% endautoescape %}

As Django template system automatically escapes everything by default you would probably never need to use the above code. Instead, we generally use autoescape tag to turn off escaping for a large section of the content. For example:

1
2
3
4
5
{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
{% endautoescape %}

escape filter #

The escape filter converts the following character to its HTML entities.

  • " is replaced with &quot;
  • ' is replaced with &#39;
  • & is replaced with &amp;
  • < is replaced with &lt;
  • > is replaced with &gt;

Since Django template system automatically escapes everything, you would never probably never use escape filter: For example:

my_code = "<p>this is short para</p>"
{{ my_code }}

is same as

{{ my_code|escape }}

The utility of this filter comes into play when we want to escape content when autoescape is turned off. For example:

1
2
3
4
5
6
{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
    {{ comments }}
{% endautoescape %}

Here It's fine to assume that contents of variables heading, main_content and footer are safe. But this is not the case with the comments variable. That's why it not a good idea to turn-off escaping for the comments variable. To escape comments variable in the template you could do the following:

1
2
3
4
5
6
{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
    {{ comments|escape }}
{% endautoescape %}

That's enough filters, to begin with. To view a full list of filters checkout this page in the Django documentation.