Шаблон Django - Увеличивает значение переменной - PullRequest
20 голосов
/ 28 декабря 2011

У меня есть следующий код в моем шаблоне

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

Ответы [ 3 ]

26 голосов
/ 28 декабря 2011

Изменять состояние объекта в шаблоне 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 %}
12 голосов
/ 29 декабря 2011

Несмотря на то, что на этот вопрос ответили, и это противоречит тому, что было сказано, у меня просто возникла мысль, и я не вижу слишком большого вреда, если, возможно, вы сделали простой класс счетчика, такой как

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 }} и т. Д.

0 голосов
/ 28 декабря 2011

Я только что узнал ответ сам.Как я уже сказал, я использовал этот пользовательский тег , который присваивает значение переменной.Что на самом деле делает, так это устанавливает значение переменной 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> %}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...