Django Template-incrément la valeur d'une variable

j'ai le code suivant dans mon template

{% 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 %}

I paramétrant la valeur d'une variable en utilisant ce personnaliser la balise et ce que je veux faire est d'incrémenter la valeur seulement si le if boucle est satisfait. Je sais {{counter++}} ne fonctionne pas. Mais comment puis-je écrire une balise personnalisée qui ferait la même tâche?

17
demandé sur Sachin 2011-12-28 22:06:15

3 réponses

Modification de l'état d'un objet dans un modèle Django est découragé. Vous devriez probablement mordre la balle, calculer la condition à l'avance et passer l'état supplémentaire au modèle de sorte que vous pouvez simplifier la logique du modèle.

Je ne suis pas puriste à cet égard d'ailleurs, mais j'ai été mordu par les limitations délibérées des gabarits de Django à quelques reprises. Tu ferais mieux de ne pas te battre, à mon avis.

que votre intention semble être de filtrer non-correspondance des éléments, une autre solution serait de filtrer ceux de la vue et ensuite utiliser {{ forloop.counter }} pour trier le texte du lien que vous voulez. Donc dans la vue vous avez quelque chose comme ceci:

new_lst = filter(lambda x: x.attr0 == attr0 and x.attr1 == attr1, lst)

Et puis, dans votre template:

{% for object in new_lst %}
   <li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li>
{% endfor %}
24
répondu Eduardo Ivanec 2011-12-28 19:30:11

bien que cela ait été répondu et va à l'encontre de ce qui a été dit j'ai juste eu une pensée et ne peut pas voir trop de mal si peut-être vous avez fait simple contre classe comme

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 ''

puis dans votre template {{ counter.increment }}{{ counter.count }} etc.

11
répondu T I 2016-11-11 20:34:48

je viens de trouver la réponse moi-même. Comme je l'ai dit j'ai été en utilisant cette balise personnalisée, qui assigne une valeur à une variable. Ce qui est fait n'est définie de donner une valeur à une variable dans le context donc j'ai juste récupéré la valeur du contexte et de l'incrémentée.

Voici le code

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)

Il peut être utilisé comme ceci {% increment <var_name> %} mais ce var_name devrait avoir été défini à une valeur précédemment en utilisant la balise personnalisée mentionnée ci-dessus comme {% set <var_name> = <var_value> %}

0
répondu Sachin 2011-12-28 18:39:13