2012-07-26 17 views
5

(tl; dr na dole)Django, szablony, pętle i cykle

Pozwól mi spróbować wyjaśnić, co próbuję wykonać: Mam dwuwymiarowej tablicy, i chciałbym, aby wyświetlić jego zawartość w pewien sposób. Chcę "wierszy", a każdy wiersz może wyświetlać nie więcej niż trzy "obiekty", z braku lepszego słowa. Tak więc chcę iterować po tablicy i utworzyć mój HTML w procesie. Mój pomysł jest następujący: każdy "pierwszy z trzech" elementów w tablicy powinien otworzyć "rząd". Każdy "trzeci z trzech" elementów powinien zamknąć "rząd". Jednakże, jeśli ostatni element w tablicy [inner] nie jest "trzecim z trzech", to powinien zamknąć wiersz. Tak więc, na przykład, gdybyśmy mieli coś L=[ [0,1,2,3,4], [5,6,7] ], że chciałby, aby wyświetlić ją tak:

0 1 2 
3 4 

5 6 7 

co może być oznaczony jak:

<div>0 1 2</div> 
<div>3 4</div> 
<div>5 6 7</div> 

Moja pierwsza myśl była po prostu użyć modulo operator i zobacz, czy każda iteracja była "pierwsza", "druga", czy "trzecia" z rzędu, ale szablony Django nie obsługują bezpośrednio modulo (więcej o tym później).

Więc wymyśliłem kodzie szablonu takich jak to:

{% for x in L %} 
{% for y in x %} 
    {% cycle '<div>' '' '' %} 
    {{ y }} 
    {% cycle '' '' '</div>' %} 
{% endfor %}<br/> 
{% endfor %} 

I to był dobry początek. Biorąc powyższy przykład, na 0 otworzymy div, na 1 nic nie rób, na 2 zamknij div, na 3 otwórz go, a na 4 ... cóż, to nie zamknie, ponieważ 4 nie był "trzeci w serii 3 ". Tak więc, podczas gdy szablony Django nie mają modulo, mają one podzielny check, więc wymyśliłem dodatkową logikę, aby powiedzieć, że jeśli trafimy na ostatni element pętli for [inner], to również nie jest podzielna przez 3 (więc nie mamy duplikatu blisko), a następnie zamknij dział:

{% for x in z %} 
{% for y in x %} 
    {% cycle '<div>' '' '' %} 
    {{ y }} 
    {% cycle '' '' '</div>' %} 

    {% if forloop.last %} 
    {% if forloop.counter|divisibleby:"3" %} 
    <!-- Row Already Closed --> 
    {% else %} 
    </div> 
    {% endif %} 
    {% endif %} 

{% endfor %}<br/> 
{% endfor %} 

To zadziałało lepiej! Teraz przejrzałem całą pierwszą tablicę wewnętrzną z odpowiednim znacznikiem. Mój problem jest następujący: najwyraźniej funkcja cyklu Django nie resetuje się po wyjściu poza zakres wewnętrznej pętli for. Oznacza to, że mój numer 5 z powyższego przykładu nie otwiera elementu div, tak jak powinien, nie jest rozpoznawany jako pierwszy w cyklu. W rzeczywistości jest on rozpoznawany jako trzeci, a więc zamyka div!

Więc nie jestem pewien, dokąd się udać. Wygląda na to, że jest to known and unfixed issues in Django. Czy ktoś może pomóc?

tl; dr Chcę wziąć tablicę 2d, np. L=[ [0,1,2,3,4], [5,6,7] ] i odpowiednio oznaczyć go grupowania nie więcej niż 3 w czasie i bez żadnych grupowania elementów z wielu tablic razem, tak jak poniżej:

0 1 2 
3 4 

5 6 7 

Jaki byłby kod szablonu, który i dlaczego?

Odpowiedz

14

Powinieneś być w stanie wykorzystać {% if forloop.counter0|divisibleby:"3" %} do określenia, kiedy otworzyć tag <div> i {% if forloop.last or forloop.counter|divisibleby:"3" %} do określenia, kiedy zamknąć znacznik </div>.

{% for x in z %} 
{% for y in x %} 
    {% if forloop.counter0|divisibleby:"3" %}<div>{% endif %} 
    {{ y }} 
    {% if forloop.last or forloop.counter|divisibleby:"3" %}</div>{% endif %} 
{% endfor %}<br/> 
{% endfor %} 
+0

Doskonale, dziękuję! – Joseph