Template filters in Django

While setting up a HTML template, you can utilize Python objects or even some of their methods for your benefit. Although, Python isn’t the principle means of working with HTML pages, so you should be familiar with different tools of manipulating data, for example, template filters.

Filters

You can utilize strings as arguments to the built-in len function in Python, however you can’t utilize functions with arguments in templates. To get the size of a string in a template, we can utilize DTL filters.

Filters are special operations that work like Python functions: they receive arguments and return the result of their processing. For instance, we can utilize the length filter to get the size of a string.

To use length in a template, apply this sequence: expression, pipe operator, filter. Pass an expression to the filter and get the result.

{{ "Lorem ipsum" | length }}

It works not only with constants but with any of your variables.

Filters with arguments

At-times, we need to make basic math calculations, for instance, find the sum of two numbers. Bad news is, you can’t do math in template with the operators + and – like in Python. Good news is, we can utilize filters with arguments for this purpose!

To add two numbers in a template, add a colon after the filter and pass the second argument to it:

{{ 1000 | add:5000 }}

Don’t forget to use a colon! If you omit it, the template won’t work.

As you see, the syntax is not that different, and there’s nothing scary about additional arguments.

Only some filters have arguments. Please refer to the documentation to prevent mistakes in your code and see what other filters Django has to offer.

Pipelines

One filter is fine yet at times we have to combine them, just like calling a function from another function. In such circumstances, we can utilize pipelines.

Pipelines take their name from the utilization of pipe operators that pass the result of the filter processing through a pipe to the next filter. Utilizing two, three, or four filters isn’t too different from utilizing only one because the syntax remains the same, and the result of the previous step becomes the input to the next.

For instance, say we want to show the count of page visits to our users. Assuming that something awful may occur and we forget to pass the necessary variable, we utilize the default value to show at least 0 views and hence make the layout of the page steady

{{ counter | default:0 | add:1 }}

We also add 1 to the counter to account for the current view of the page.

Example

Let us redesign any blog of our choice. Here we are using a blog project which we used in the previous article. Let’s add some extra information for every post we made. Here is what John’s blog (which we used) first post looked like:

import datetime

post = {
    "created_at": datetime.datetime(2019, 5, 20, 14, 15, 43),
    "text": "My first post",
    "comments": [
        "My congratulations!!",
        "Looking forward to the second one",
    ],
}

Let’s count the number of words in it, display when the record was created, and how many likes it has now:

<html>
  <body>
    <div>{{ post.text }}</div>
    <div>There are {{ post.text.split | length }} words in a post</div>
    <div>Created at: {{ post.created_at | date:"Y.m.d" }}</div>
    <div>Likes: {{ post.likes | default:0 | add:1 }}</div>
    <div>{{ post.comments | join:"<br />" }}</div>
  </body>
</html>

Notice how even though we forget to pass likes in the initial structure of a post, the default filter provides us the zero value.

Check the documentation for the information on the date and join filters.

Conclusion

Let’s recap: in this topic, we learned what templates filters are and how we can use them. Filters are just like Python functions: some of them have arguments, others don’t, and just like with functions, we can combine them to get the final result.