2010-03-23 8 views
14

nella mia applicazione Django 1.1.1 Ho una funzione nella vista che restituisce al suo modello un intervallo di numeri e un elenco di elenchi di elementi, ad esempio :Utilizzo del valore forloop.counter come indice di lista in un modello Django

... 
data=[[item1 , item2, item3], [item4, item5, item6], [item7, item8, item9]] 
return render_to_response('page.html', {'data':data, 'cycle':range(0,len(data)-1]) 

All'interno del modello ho un esterno per ciclo, che contiene anche un altro per il ciclo per visualizzare nell'output contiene delle liste interne di dati in questo modo

... 
{% for page in cycle %} 
... 
<table> 
{% for item in data.forloop.counter0 %} 
<tr><td>{{item.a}} </td> <td> {{item.b}} ... </td> </tr> 
... 
</table> 
{% endfor %} 
{% if not forloop.last %} 
< div class="page_break_div" > 
{% endif %} 
{% endfor %} 
... 

Ma Django motore di template non funziona con il valore forloop.counter0 come indice per t elenca (invece lo fa se inserisco manualmente un valore numerico come indice). C'è un modo per far funzionare il loop lista con il valore esterno forloop.counter0? Grazie in anticipo per l'aiuto :)

risposta

12

Non è possibile utilizzare le variabili per i nomi degli attributi, le chiavi del dizionario o gli indici di elenco.

Anche range(0,len(data)-1] non è Python valido. Dovrebbe essere range(len(data)).

Probabilmente non è necessario cycle. Forse quello che vuoi è questo:

{% for itemlist in data %} 
    ... 
    <table> 
     {% for item in itemlist %} 
     <tr><td>{{item.a}} </td> <td> {{item.b}} ... </td> </tr> 
     ... 
     {% endfor %} 
    </table> 
    {% if not forloop.last %} 
     <div class="page_break_div"> 
    {% endif %} 
{% endfor %} 
+0

Grazie Stefanw, è esattamente quello che stavo cercando di fare, non ho pensato a iterare sulla lista perché nel caso di 'len (data) == 1' (sì, il quello che ho scritto prima non era una buona dichiarazione di python) Dovevo mostrare l'output della lista in un modo diverso. Comunque ora sembra che tutto funzioni, grazie ancora per il tuo aiuto! – Alex

+0

Questo è sicuramente il modo giusto per farlo, ma [qui] (http://stackoverflow.com/a/11784863/456848) è il modo in cui aggiro le "no variabili come nomi di attributi, chiavi del dizionario o indici di elenchi" problema. È inelegante essere sicuri, ma lo fa mentre usa solo tag e filtri integrati. –

17

ho risolto questo in un modo piuttosto inefficiente. Si prega di non vomitare sul tuo computer quando leggi questo codice. Dati due elenchi di lunghezza identica, itererà attraverso il primo e stamperà l'oggetto corrispondente dal secondo.

Se è necessario utilizzare questo, utilizzarlo solo per i modelli a cui si accede raramente in cui la lunghezza di entrambi gli elenchi sarà ridotta. Idealmente, rifatta i dati del tuo modello per evitare del tutto questo problema.

{% for list1item in list1 %} 
    {% for list2item in list2 %} 
     {% if forloop.counter == forloop.parentloop.counter %} 
      {{ list1item }} {{ list2item }} 
     {% endif %} 
    {% endfor %} 
{% endfor %} 
+2

Non riesco davvero a immaginare una situazione in cui questa sarebbe la migliore soluzione possibile. – acjay

3

volevo avere i colori si alternano nella mia tabella utilizzando un foglio di stile, passando un elenco di commutazione Vero/Falso valori. Ho trovato questo davvero frustrante. Alla fine ho creato un elenco di voci del dizionario con le stesse chiavi dei campi nella tabella, più un altro con il valore true/false commutabile.

def jobListView(request): 
    # django does not allow you to append stuff to the job identity, neither 
    # will it allow forloop.counter to index another list. The only solution 
    # is to have the toggle embedded in a dictionary along with 
    # every field from the job 
    j     = job.objects.order_by('-priority') 
    # have a toggling true/false list for alternating colours in the table 
    theTog    = True 
    jobList    = [] 
    for i in j: 
     myJob   = {} 
     myJob['id']  = i.id 
     myJob['duty'] = i.duty 
     myJob['updated'] = i.updated 
     myJob['priority'] = i.priority 
     myJob['description'] = i.description 
     myJob['toggle'] = theTog 
     jobList.append(myJob) 
     theTog   = not(theTog) 
    # next i 

    return render_to_response('index.html', locals()) 
# end jobDetaiView 

e il mio modello

{% if jobList %} 
    <table border="1"><tr> 
    <th>Job ID</th><th>Duty</th><th>Updated</th><th>Priority</th><th>Description</th> 
    </tr> 

    {% for myJob in jobList %} 

     <!-- only show jobs that are not closed and have a positive priority. --> 
     {% if myJob.priority and not myJob.closeDate %} 
      <!-- alternate colours with the classes defined in the style sheet --> 
      {% if myJob.toggle %} 
       <tr class=d1> 
      {% else %} 
       <tr class=d0> 
      {% endif %} 

      <td><a href="/jobs/{{ myJob.id }}/">{{ myJob.id }}</td><td>{{ myJob.duty }}</td> 
      <td>{{ myJob.updated }}</td><td>{{ myJob.priority }}</td> 
      <td class=middle>{{ myJob.description }}</td> 
      </tr> 
     {% endif %} 
    {% endfor %} 
    </ul> 
{% else %} 
    <p>No jobs are in the system.</p> 
{% endif %} 
Problemi correlati