Подтвердить что ты не робот

Шаблон 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++}} не работает. Но как я могу написать собственный тег, который будет выполнять ту же задачу?

4b9b3361

Ответ 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> %}