it-swarm.com.ru

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

20
Sachin

Изменять состояние объекта в шаблоне 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 %}
25
Eduardo Ivanec

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

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

12
T I

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

0
Sachin