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 [email protected]. I’d greatly appreciate your feedback! :)