Шаблон Django - увеличение значения переменной
У меня есть следующий код в моем шаблоне
{% set counter = 0 %}
{% for object in object_list %}
{% if object.attr1 == list1.attr1 and object.attr2 = list2.attr2 %}
<li><a href="{{ object.get_absolute_url }}"> Link {{counter++}} </a></li>
{% endif %}
{% endfor %}
Я устанавливаю значение переменной с помощью этого настраиваемого тега, и то, что я хочу сделать, - это увеличить значение, только если цикл if
будет выполнен. Я знаю, что {{counter++}}
не работает. Но как я могу написать собственный тег, который будет выполнять ту же задачу?
Ответы
Ответ 1
Изменение состояния объекта в шаблоне Django не рекомендуется. Вероятно, вы должны укусить пулю, предварительно рассчитать условие и передать дополнительное состояние шаблону, чтобы упростить логику шаблона.
Я не пурист в этом отношении, но я был укушен целенаправленными ограничениями шаблонов Django несколько раз. На мой взгляд, вам лучше не бороться с этим.
Предполагая, что ваше намерение состоит в том, чтобы отфильтровать несогласованные элементы, альтернативой будет отфильтровывать те, которые есть в представлении, а затем использовать {{ forloop.counter }}
, чтобы отсортировать текст ссылки, который вы хотите. Итак, у вас есть что-то вроде этого:
new_lst = filter(lambda x: x.attr0 == attr0 and x.attr1 == attr1, lst)
И затем, в вашем шаблоне:
{% for object in new_lst %}
<li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li>
{% endfor %}
Ответ 2
Несмотря на то, что на это был дан ответ, и он идет вразрез с тем, что было сказано, я просто подумал и не вижу слишком большого вреда, если, возможно, вы создали простой класс-счетчик, например
class Counter:
count = 0
def increment(self):
self.count += 1
return ''
def decrement(self):
self.count -= 1
return ''
def double(self):
self.count *= 2
return ''
затем в вашем шаблоне {{ counter.increment }}
{{ counter.count }}
и т.д.
Ответ 3
Я только что узнал ответ сам. Как я уже сказал, я использовал этот настраиваемый тег, который присваивает значение переменной. То, что на самом деле установлено, задает значение переменной в context
, поэтому я просто получил значение из контекста и увеличил его.
Вот код
class IncrementVarNode(template.Node):
def __init__(self, var_name):
self.var_name = var_name
def render(self,context):
value = context[self.var_name]
context[self.var_name] = value + 1
return u""
def increment_var(parser, token):
parts = token.split_contents()
if len(parts) < 2:
raise template.TemplateSyntaxError("'increment' tag must be of the form: {% increment <var_name> %}")
return IncrementVarNode(parts[1])
register.tag('increment', increment_var)
Его можно использовать как {% increment <var_name> %}
, но это значение var_name должно быть установлено ранее, используя специальный тег, упомянутый выше, как {% set <var_name> = <var_value> %}