Search code examples
pythondjangojinja2

TemplateSyntaxError Could not parse the remainder


I have this bit of jinja2 in my Django template:

{% for filesystem, total_quota, total_usage, df_usage in totals_by_filesystem %}
  <tr>
    <td>{{ filesystem }}</span></td>
    <td>{{ total_quota | filesizeformat }}</td>
    <td>{{ total_usage | filesizeformat }}</td>
    <td>{{ df_usage * 100 }}</td>
  </tr>
{% endfor %}

When I run it I get this error message:

Exception Type: TemplateSyntaxError
Exception Value:    
Could not parse the remainder: ' * 100' from 'df_usage * 100'

I am pretty sure my syntax {{ df_usage * 100 }} is correct. What am I missing here?


Solution

  • Django's template language does not allow complex expressions, so {{ x * 100 }}, as simple as it seems, is not evaluated by Django.

    There are essentially three options:

    1. use a template tag

    the {% widthratio … %} template tag [Django-doc] essentially implements the rule of three [wiki], although this is more designed for charts. It will divide by the second operand, and then multiply by the third and round the result, so:

    {% widthratio df_usage 1 100 %}
    

    divides by one (no effect) multiplies by 100 and then rounds the result.

    2. prepare the result in the view

    Instead of doing arithmetic in the view, which is also not very efficient, you can prepare the items in the view with:

    totals_by_filesize = [
        (filesystem, total_quota, total_usage, 100 * df_usage)
        for (filesystem, total_quota, total_usage, df_usage) in totals_by_filesystem
    ]

    3. use jinja

    Django's template language does not support several features, this has been done deliberately to prevent people from writing business logic in the templates. One can use Jinja as a template language, but this is not necessary and to some extent counterproductive, precisely to prevent writing business logic in the template.