2011-12-28 52 views
17

tengo el siguiente código en mi plantillaplantilla de Django - Incrementar el valor de una variable

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

que establecer el valor de una variable usando este custom tag y lo que quiero hacer es incrementar el valor sólo si el circuito if está satisfecho. Sé que {{counter++}} no funciona. Pero, ¿cómo puedo escribir una etiqueta personalizada que haría la misma tarea?

Respuesta

24

No se recomienda cambiar el estado de un objeto en una plantilla de Django. Probablemente deberías morder la bala, calcular la condición de antemano y pasar un estado extra a la plantilla para que puedas simplificar la lógica de la plantilla.

No soy purista en este sentido por cierto, pero me han mordido algunas veces las limitadas limitaciones de las plantillas de Django. Es mejor que no luches contra eso, en mi opinión.

Siendo que su intención parece ser filtrar los elementos que no coinciden, una alternativa sería filtrar los de la vista y luego usar {{ forloop.counter }} para ordenar el texto del enlace que desea. Así, en la vista que se tiene algo como esto:

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

Y luego, en su plantilla:

{% for object in new_lst %} 
    <li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li> 
{% endfor %} 
+1

1 respuesta agradable, [referencia] (https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for) perdón por el juego de palabras –

+0

Generalmente no trato de eludir las limitaciones de Django, pero esta vez realmente necesitaba hacerlo ... En mi condición '{{forloop.counter}}' no ayuda. Sin embargo, he dado mi código de plantilla, ¿puedes decir si puedo usar '{{forloop.counter}}' – Sachin

+0

+1 Usar el contador de bucle es el camino a seguir aquí. @Sachin: si quieres usar cero '{{forloop.counter0}}', sin embargo. –

0

acabo de encontrar la respuesta a mí mismo. Como dije, estaba usando this custom tag, que asigna un valor a una variable. Lo que en realidad se establece es establecer un valor para una variable en el context, así que acabo de recuperar el valor del contexto y lo incrementé.

Este es el código

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) 

Puede ser utilizado como esto {% increment <var_name> %} pero esto var_name debería haberse fijado a un valor previamente usando la etiqueta personalizada se mencionó anteriormente como {% set <var_name> = <var_value> %}

+0

Estoy teniendo un comportamiento extraño con esto.mis actualizaciones no se guardan en un bucle incrustado, como si un espacio de nombres secundario se copiara temporalmente, luego se borrase una vez que el bucle for se hubiera ido, ¿alguna idea? – Jeremy

10

Aunque esto ha sido contestada y va en contra de lo que se ha dicho, acabo de tener un pensamiento y no puedo ver demasiado daño si tal vez hiciste una clase contraria simple como

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

entonces en su plantilla {{ counter.increment }}{{ counter.count }} etc.

+1

Pero, ¿cómo voy a vincular esto con el nodo Plantilla? – Sachin

+0

no fue diseñado para funcionar como una etiqueta recién aprobada como parte del contexto –

+0

¡Oh! esa solución que ya tenía yo quería algo relacionado con la plantilla – Sachin

Cuestiones relacionadas