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:
{{ 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:
{{ value|filter_name:"argument" }}
You can chain multiple filters together, applying them from left to right:
{{ 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
{{ "HELLO WORLD"|lower }} <!-- Output: hello world -->
{{ "hello world"|upper }} <!-- Output: HELLO WORLD -->
title
and capfirst
{{ "hello world"|title }} <!-- Output: Hello World -->
{{ "hello world"|capfirst }} <!-- Output: Hello world -->
truncatechars
and truncatewords
{{ "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:
{{ "<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:
{{ "First line\nSecond line"|linebreaks }}
<!-- Output: <p>First line<br>Second line</p> -->
urlize
Converts URLs in text to clickable links:
{{ "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:
{{ 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:
{{ value|join:", " }}
<!-- If value is ['apple', 'banana', 'cherry'], outputs: apple, banana, cherry -->
length
Returns the length of a list or a string:
{{ 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:
{{ 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:
{{ 5|add:3 }} <!-- Output: 8 -->
{{ 5|add:-3 }} <!-- Output: 2 -->
divisibleby
Checks if the value is divisible by the argument:
{{ 21|divisibleby:3 }} <!-- Output: True -->
{{ 21|divisibleby:4 }} <!-- Output: False -->
Conditional Filters
default
Provides a default value if the variable evaluates to False:
{{ value|default:"Nothing to display" }}
<!-- If value is empty, outputs: Nothing to display -->
yesno
Maps True, False, and None to custom strings:
{{ 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:
<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:
- Format the post title with
title
- Provide a default author name with
default
- Format the date with
date
- Join tags with commas using
join
- Show a truncated excerpt with
truncatewords
and format line breaks withlinebreaks
- Count words with
wordcount
- 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:
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:
{% 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:
{{ value|filter1|filter2:"arg"|filter3 }}
For example:
{{ "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:
{% 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
-
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
-
Implement a custom filter that converts a number to its ordinal form (e.g., 1 to "1st", 2 to "2nd", etc.)
-
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! :)