[Answered ]-Parsing forloop.counter in form's label in Django

2👍

We can’t use a Django variable using {{ }} inside another Django tag {% %}.

Django in its docs has not used {{ }} inside a template tag {% %} anywhere. Everywhere, it has used it separately.

For example:

Following 2 code snippets are valid.

{% firstof var1 var2 var3 %} # valid
<li> {{ some_variable }} </li> # valid

But, this code snippet is invalid.

{% firstof var1 var2 {{some_var}} %} # invalid

What can be done then?

We know that a variable which is present already in a template can be assigned inside a template tag {% %}. So, if we compute a variable my_label beforehand then we can directly assign this variable in our template tag.

{% formfield field with label=my_label %} # our target

So, we need to compute the value "blablabla<x>" where x is the value of forloop.counter and store it in a variable my_label.

Computing and storing the label value in a separate variable

To store a value in a variable, we can use the built-in with template tag.

We might be tempted to use the below line to compute my_label variable, but it will lead to error as we are using the same variable syntax in a template tag again.

{% with my_label="blablabla{{forloop.counter}}" %} # invalid

So, we need to approach the problem now differently. We have to concatenate choice with the value of forloop.counter to get blablabla1, blablabla2 and so on and we know there exists a template filter add which adds the argument to the value. We can use this filter.

So, we try the below code.

{% with my_label="blablabla"|add:forloop.counter %} # will still not work 

But this will still not solve our problem. An empty string '' will be assigned to my_label variable as we are trying to add an integer forloop.counter with a string "blablabla". On adding an integer with string, an error will be raised and in case of errors, Django will assign an empty string to it.

As per docs on add filter:

This filter will first try to coerce both values to integers. If this
fails, it’ll attempt to add the values together anyway. This will work
on some data types (strings, list, etc.) and fail on others. If it
fails, the result will be an empty string.

So, we need to convert the value of forloop.counter to a string first and store it in a variable counter_value. This can be done using stringformat built-in template filter. Then we can use the add filter.

{% with counter_value=forloop.counter|stringformat:"s" %}  # assign counter value to a variable
{% with my_label="blablabla"|add:counter_value %} # compute value of 'my_label'

Now, we have the value of my_label with us and we can use it to get the desired result.

{% formfield field with label=my_label %} # use your label variable here

Final code:

{% for field in form %}

    {% with counter_value=forloop.counter|stringformat:"s" %} 
    {% with my_label="blablabla"|add:counter_value %} 
    {% formfield field with label=my_label %}
    {% endwith %}
    {% endwith %}

{% endfor %}

Note: I was trying a slightly different version of code instead of the originally posted answer(given below) which did not lead to errors OP was getting. Thanks @Daniel for correcting the mistake.

The previously posted answer i.e the below code will not work as inside a Django tag {% %}, we can’t put {{ }}.

# this initially posted code won't work
{% formfield field with label='blablabla {{ forloop.counter|stringformat:"s" }}' %}

Leave a comment