Django - Variable Cached With "with" Template Tag Isn't Evaluated
I'm following along this article, and I have a form like this:
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
I figured, since there are multiple instances of "choice{{ forloop.counter }}"
, I can cache it with with
template tag and use it as a variable. But as you can see, the variable forloop.counter
inside the with
template tag isn't evaluated.
The expected result was this:
How can I fix this?
Answer
The variable using {{ }}
cannot be used inside {% %}Built-in tag[Django-doc] but we can use the variable
inside {% %}
if it is already available in the template. So we have to get the value before and we can set that value using with[Django-doc]. But the value you are getting is dynamic with every loop you get new value with {{forloop.counter}}
and the same thing we cannot use {{ }}
inside {% %}
.So you can concatenate the values differently i.e. {{forloop.counter}}
and choice
.
For concatenate
we can use add Built-in filter[Django-doc] as documented
Adds the argument to the value. 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.
But the problem with add
is as Warned
as
Strings that can be coerced to integers will be summed, not concatenated,
So we have to convert the {{forloop.counter}}
to string first before concatenation and we can use stringformat[Django-doc] for that and store the value and use that value as
{% for choice in question.choice_set.all %}
{% with counter=forloop.counter|stringformat:"s" %}
{% with choice_id="choice"|add:counter %}
<input type="radio" name="choice" id={{choice_id}} value="{{ choice.id }}">
<label for={{choice_id}}>{{ choice.choice_text }}</label><br>
{% endwith %}
{% endwith %}
{% endfor %}
Related Questions
- → What are the pluses/minuses of different ways to configure GPIOs on the Beaglebone Black?
- → Django, code inside <script> tag doesn't work in a template
- → React - Django webpack config with dynamic 'output'
- → GAE Python app - Does URL matter for SEO?
- → Put a Rendered Django Template in Json along with some other items
- → session disappears when request is sent from fetch
- → Python Shopify API output formatted datetime string in django template
- → Can't turn off Javascript using Selenium
- → WebDriver click() vs JavaScript click()
- → Shopify app: adding a new shipping address via webhook
- → Shopify + Python library: how to create new shipping address
- → shopify python api: how do add new assets to published theme?
- → Access 'HTTP_X_SHOPIFY_SHOP_API_CALL_LIMIT' with Python Shopify Module