2011-12-28 12 views
17

Ho il seguente codice nel mio modelloDjango Template - Incrementare il valore di una variabile

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

ho l'impostazione del valore di una variabile utilizzando questo custom tag e quello che voglio fare è quello di incrementare il valore solo se il ciclo if è soddisfatto. So che lo {{counter++}} non funziona. Ma come posso scrivere un tag personalizzato che farebbe lo stesso compito?

risposta

24

La modifica dello stato di un oggetto in un modello Django è sconsigliata. Probabilmente dovresti mordere il proiettile, calcolare la condizione in anticipo e passare lo stato extra al modello in modo da poter semplificare la logica del modello.

A proposito, non sono un purista, ma sono stato morso alcune volte dalle limitazioni significative dei modelli Django. È meglio non combatterlo, secondo me.

Essendo che l'intenzione sembra essere quella di filtrare gli elementi non corrispondenti, un'alternativa sarebbe quella di filtrare quelli nella vista e quindi utilizzare {{ forloop.counter }} per risolvere il testo del collegamento che si desidera. Quindi, in vista di avere qualcosa di simile:

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

E poi, nel modello:

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

1 bella risposta, [di rinvio] (https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for) , scusate il gioco di parole –

+0

Generalmente non cerco di aggirare i limiti di Django ma stavolta avevo davvero bisogno di farlo .... Nelle mie condizioni '{{forloop.counter}}' non aiuta. Ho comunque dato il mio codice template, puoi dire se posso usare '{{forloop.counter}}' – Sachin

+0

+1 Usare il contatore forloop è il modo per andare qui. @Sachin: se vuoi usare l'uso a base zero '{{forloop.counter0}}', comunque. –

0

ho appena trovato la risposta me stesso. Come ho detto, stavo usando this custom tag, che assegna un valore a una variabile. Quello che in realtà fa è impostare dare un valore ad una variabile nel così ho appena recuperato il valore dal contesto e l'ho incrementato.

Ecco il codice

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) 

Può essere utilizzato come questo {% increment <var_name> %} ma questo nome_var avrebbe dovuto essere impostato su un valore precedentemente utilizzando il tag personalizzato di cui sopra come {% set <var_name> = <var_value> %}

+0

Sto ottenendo un comportamento strano con questo.i miei aggiornamenti non vengono salvati in un loop incorporato, come se uno spazio dei nomi secondario venisse copiato temporaneamente, quindi cancellato una volta che il ciclo for è sparito, qualche idea? – Jeremy

10

Anche se questo è stato risposto e va contro ciò che è stato detto Ho appena avuto un pensiero e non posso vedere troppo male se forse hai fatto semplice contro classe come

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

poi nel modello {{ counter.increment }}{{ counter.count }} ecc

+1

Ma come collegherò questo con il nodo Modello? – Sachin

+0

non era pensato per funzionare come tag appena passato come parte del contesto –

+0

Oh! quella soluzione avevo già voluto qualcosa correlato al modello – Sachin

Problemi correlati