Django - Переменная, кэшируемая тегом шаблона "with", не оценивается
Я следую этой статье, и у меня есть такая форма:
<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>
Я подумал, что поскольку существует несколько экземпляров "choice{{ forloop.counter }}", я могу кэшировать его с помощью тега шаблона with и использовать его как переменную. Но, как вы видите, переменная forloop.counter внутри шаблонного тега with не оценивается.
Ожидаемый результат был следующим:
Как я могу это исправить?
Переменная, использующая {{ }}, не может быть использована внутри {% %}Built-in tag[Django-doc], но мы можем использовать variable внутри {% %}, если она уже доступна в шаблоне. Поэтому мы должны получить значение раньше и можем установить его с помощью with[Django-doc]. Но значение, которое вы получаете, является динамическим, с каждым циклом вы получаете новое значение с помощью {{forloop.counter}} и то же самое мы не можем использовать {{ }} внутри {% %}. Поэтому вы можете конкатенировать значения по-другому, т.е. {{forloop.counter}} и choice.
Для concatenate мы можем использовать add Built-in filter[Django-doc] как документировано
Добавляет аргумент к значению. Этот фильтр сначала попытается привести оба значения к целым числам. Если это не удастся, он все равно попытается сложить значения. Это сработает для некоторых типов данных (строки, список и т.д.) и не сработает для других.
Но проблема с add такая же Warned как и
Strings that can be coerced to integers will be summed, not concatenated,
Поэтому перед конкатенацией нам нужно сначала преобразовать {{forloop.counter}} в строку, для чего мы можем использовать stringformat[Django-doc], сохранить значение и использовать его как
{% 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 %}

