Skip to main content

Django Template Filters

Introduction​

Django template filters are a powerful feature that allows you to modify variables and values when they are rendered in your templates. They act like small utility functions that transform data for display, such as formatting dates, converting text to lowercase, truncating strings, or performing calculations. Template filters are an essential tool for creating dynamic and well-formatted content in your Django applications without requiring additional view logic.

In this tutorial, we'll explore how Django template filters work, learn about the built-in filters Django provides, and even see how to create your own custom filters.

How Template Filters Work​

Template filters in Django follow a simple syntax:

django
{{ value|filter_name }}

The pipe character (|) separates the value from the filter that will be applied to it. Some filters also accept arguments, which are specified using a colon:

django
{{ value|filter_name:"argument" }}

You can chain multiple filters together, applying them from left to right:

django
{{ value|filter1|filter2|filter3 }}

Commonly Used Built-in Filters​

Django comes with numerous built-in filters. Let's look at some of the most commonly used ones with examples:

Text Transformation Filters​

lower and upper​

django
{{ "HELLO WORLD"|lower }}  <!-- Output: hello world -->
{{ "hello world"|upper }} <!-- Output: HELLO WORLD -->

title and capfirst​

django
{{ "hello world"|title }}    <!-- Output: Hello World -->
{{ "hello world"|capfirst }} <!-- Output: Hello world -->

truncatechars and truncatewords​

django
{{ "This is a long sentence that will be truncated."|truncatechars:20 }}
<!-- Output: This is a long sen... -->

{{ "This is a long sentence that will be truncated."|truncatewords:4 }}
<!-- Output: This is a long ... -->

HTML and URLs​

safe​

Marks a string as safe HTML, preventing Django from escaping it:

django
{{ "<b>Bold text</b>"|safe }} <!-- Output: Bold text (rendered as bold) -->

⚠️ Warning: Only use safe with content you trust to prevent XSS vulnerabilities.

linebreaks​

Converts newlines into HTML <br> and <p> tags:

django
{{ "First line\nSecond line"|linebreaks }}
<!-- Output: <p>First line<br>Second line</p> -->

urlize​

Converts URLs in text to clickable links:

django
{{ "Check out django.com"|urlize }}
<!-- Output: Check out <a href="http://django.com">django.com</a> -->

Date and Time Filters​

date​

Formats a date according to the given format:

django
{{ value|date:"Y-m-d" }} <!-- For 2023-05-15 outputs: 2023-05-15 -->
{{ value|date:"F j, Y" }} <!-- For 2023-05-15 outputs: May 15, 2023 -->

List and Dictionary Filters​

join​

Similar to Python's join method:

django
{{ value|join:", " }}
<!-- If value is ['apple', 'banana', 'cherry'], outputs: apple, banana, cherry -->

length​

Returns the length of a list or a string:

django
{{ value|length }}
<!-- If value is ['apple', 'banana', 'cherry'], outputs: 3 -->
<!-- If value is "hello", outputs: 5 -->

first and last​

Get the first or last item from a list:

django
{{ value|first }}
<!-- If value is ['apple', 'banana', 'cherry'], outputs: apple -->

{{ value|last }}
<!-- If value is ['apple', 'banana', 'cherry'], outputs: cherry -->

Numeric Filters​

add and subtract​

Adds or subtracts the argument:

django
{{ 5|add:3 }}       <!-- Output: 8 -->
{{ 5|add:-3 }} <!-- Output: 2 -->

divisibleby​

Checks if the value is divisible by the argument:

django
{{ 21|divisibleby:3 }} <!-- Output: True -->
{{ 21|divisibleby:4 }} <!-- Output: False -->

Conditional Filters​

default​

Provides a default value if the variable evaluates to False:

django
{{ value|default:"Nothing to display" }}
<!-- If value is empty, outputs: Nothing to display -->

yesno​

Maps True, False, and None to custom strings:

django
{{ value|yesno:"Yes,No,Maybe" }}
<!-- If value is True, outputs: Yes -->
<!-- If value is False, outputs: No -->
<!-- If value is None, outputs: Maybe -->

Practical Example: Blog Post Template​

Let's see how we can use these filters in a real-world example like a blog post template:

django
<div class="blog-post">
<h1>{{ post.title|title }}</h1>

<div class="metadata">
Posted by {{ post.author.username|default:"Anonymous" }}
on {{ post.created_at|date:"F j, Y" }}
</div>

<div class="tags">

</div>

<div class="excerpt">
{{ post.content|truncatewords:50|linebreaks }}
</div>

<div class="read-more">
<a href="{% url 'blog:post_detail' post.slug %}">
Read More ({{ post.content|wordcount }} words)
</a>
</div>

<div class="comments">
{{ post.comments.count|default:0 }} comment{{ post.comments.count|pluralize }}
</div>
</div>

In this example, we:

  1. Format the post title with title
  2. Provide a default author name with default
  3. Format the date with date
  4. Join tags with commas using join
  5. Show a truncated excerpt with truncatewords and format line breaks with linebreaks
  6. Count words with wordcount
  7. Properly pluralize "comment" based on count with pluralize

Creating Custom Template Filters​

Sometimes the built-in filters aren't enough. Fortunately, creating your own custom filter is straightforward.

Step 1: Create a templatetags directory​

Create a directory named templatetags inside your Django app. This directory must be a proper Python package, so include an __init__.py file:

myapp/
__init__.py
models.py
views.py
templatetags/
__init__.py
custom_filters.py

Step 2: Create a new Python module for your filters​

Create a Python file (e.g., custom_filters.py) inside the templatetags directory:

python
from django import template

register = template.Library()

@register.filter
def subtract(value, arg):
"""Subtract the arg from the value."""
return value - arg

@register.filter
def percentage(value, arg):
"""Calculate percentage."""
return (value / arg) * 100

Step 3: Load your custom filters in templates​

To use your custom filters in a template, first load the template tag library:

django
{% load custom_filters %}

<p>Result: {{ 10|subtract:5 }}</p> <!-- Output: Result: 5 -->
<p>Percentage: {{ 75|percentage:100 }}%</p> <!-- Output: Percentage: 75% -->

Advanced Filter Usage​

Filter Chaining​

As mentioned earlier, you can chain filters together to perform multiple operations:

django
{{ value|filter1|filter2:"arg"|filter3 }}

For example:

django
{{ "hello world"|capfirst|truncatechars:7 }}
<!-- Output: Hello w... -->

Filters with Template Variables​

You can use template variables as filter arguments using the with template tag:

django
{% with max_length=20 %}
{{ my_text|truncatechars:max_length }}
{% endwith %}

Summary​

Django template filters are powerful tools for manipulating and formatting data within your templates. They help keep your views cleaner by handling display-related transformations directly in the template. We've explored:

  • How to apply simple and parameterized filters
  • Many of Django's built-in filters for text, HTML, dates, lists, numbers, and conditionals
  • A real-world example showing filters in action
  • How to create custom filters for application-specific needs

Using template filters effectively allows you to create more dynamic and user-friendly templates without placing formatting logic in your view functions.

Additional Resources​

Practice Exercises​

  1. Create a template that displays a list of products with prices. Use filters to:

    • Format the prices with two decimal places
    • Sort the products alphabetically
    • Highlight products that are on sale
  2. Implement a custom filter that converts a number to its ordinal form (e.g., 1 to "1st", 2 to "2nd", etc.)

  3. Build a blog comment system that uses filters to:

    • Format comment dates as "X days/hours/minutes ago"
    • Highlight the author's comments differently
    • Truncate long comments with a "Read More" option


If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)