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 %}
Je règle la valeur d’une variable à l’aide de cette balise personnalisée et ce que je veux faire, c’est d’incrémenter la valeur uniquement si la boucle if
est satisfaite. Je sais que {{counter++}}
ne fonctionne pas. Mais comment puis-je écrire une balise personnalisée qui ferait la même tâche?
Changer l'état d'un objet dans un modèle Django est déconseillé. Vous devriez probablement mordre la balle, calculer la condition à l'avance et transmettre l'état supplémentaire au modèle afin de simplifier la logique du modèle.
Soit dit en passant, je ne suis pas un puriste à cet égard, mais les limitations délibérées des modèles Django m'ont mordu à plusieurs reprises. Tu ferais mieux de ne pas lutter contre cela, à mon avis.
Étant donné que votre intention semble être de filtrer les éléments ne correspondant pas, une alternative serait de filtrer ceux de la vue, puis utilisez {{ forloop.counter }}
pour trier le texte du lien que vous souhaitez. Donc, dans la vue, vous avez quelque chose comme ça:
new_lst = filter(lambda x: x.attr0 == attr0 and x.attr1 == attr1, lst)
Et ensuite, dans votre modèle:
{% for object in new_lst %}
<li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li>
{% endfor %}
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 je ne vois pas trop de mal si vous faisiez peut-être un simple contre-cours 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 modèle {{ counter.increment }}
{{ counter.count }}
etc.
Je viens de découvrir la réponse moi-même. Comme je l'ai dit, j'utilisais cette balise personnalisée , qui attribue une valeur à une variable. Ce qui est réellement fait est de donner une valeur à une variable dans la variable context
. Je viens donc d'extraire la valeur du contexte et de l'incrémenter.
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 nom_var devrait avoir été préalablement défini avec une valeur utilisant la balise personnalisée mentionnée ci-dessus comme {% set <var_name> = <var_value> %}
.