Smurf
Smurf

Reputation: 551

Adding a value to a variable in Django templates

This is a very quick question, which I think may be a limitation in the templates.

I'm adding a value to a variable in a template using the |add:"num" feature, I'm trying to use another variable as the number but it doesn't seem to work. Should this be possible ?

e.g.

{{ pagecontrol.start_page|add:"-pagecontrol.news_per_page" }}

Thanks in advance all.

Wayne

Upvotes: 2

Views: 4969

Answers (3)

Rahul Gupta
Rahul Gupta

Reputation: 47866

Django does not provide a built-in template tag/filter to do subtraction. Also, there is no built-in filter for converting a positive integer to negative. You would have to write a template tag for that.

Solution 1- Use a custom template filter:

@register.filter
def subtract(value, arg):
    return value - arg

Then in your template, you can do something like:

{{ pagecontrol.start_page|subtract:pagecontrol.news_per_page }}

Solution 2- Use django-mathfilters library

You can use Django-mathfilters library to get a subtract filter.

First, load mathfilters at the top of your template. Then use sub filter in your template like below:

{% load mathfilters %}

{{ pagecontrol.start_page|sub:pagecontrol.news_per_page }}

Why your code is not working?

Django Source code of add built-in filter:

@register.filter(is_safe=False)
def add(value, arg):
    """Adds the arg to the value."""
    try:
        return int(value) + int(arg)
    except (ValueError, TypeError):
        try:
            return value + arg
        except Exception:
            return ''

When you do {{ pagecontrol.start_page|add:"-pagecontrol.news_per_page" }} in your template, '-pagecontrol.news_per_page' string is passed as arg to the above add built-in filter and not its actual value, so exception is raised because of adding integer and string values. '' is returned as the final value by add filter so nothing is displayed.

NOTE:

In case of complex variables name, you can use with template tag. It will cache a complex variable under a simpler name.

Below is a sample example of using with with add filter. This will just add the values.

{% with my_variable=pagecontrol.news_per_page %}

This will store the value of pagecontrol.news_per_page in the variable my_variable. Then in your template, you can use this variable:

{{ pagecontrol.start_page|add:my_variable }}

This will add the 2 variables.

{% with my_variable=pagecontrol.news_per_page %}

    {{ pagecontrol.start_page|add:my_variable }}

{% endwith %}

Upvotes: 3

Lorenzo Peña
Lorenzo Peña

Reputation: 2263

You basically can't. Apart from what Rahul Gupta said, Django has an explicit design philosohpy to prevent advanced logic in templates (although substracting is not advanced logic at all):

The template system intentionally doesn’t allow the following:

- Assignment to variables
- Advanced logic

The goal is not to invent a programming language. The goal is to offer just enough programming-esque functionality, such as branching and looping, that is essential for making presentation-related decisions.

You could always create your own filter for substracting based on the Django core add filter, also posted by Rahul, or perform any substraction in the view.

Upvotes: 1

var211
var211

Reputation: 606

You need something like:

{{ pagecontrol.start_page|sub:pagecontrol.new_per_page }}

Upvotes: -2

Related Questions