2012-07-26 14 views
5

(tl; dr en la parte inferior)Django, plantillas, para los bucles y los ciclos

Voy a tratar de explicar lo que estoy tratando de lograr: Tengo una matriz de dos dimensiones, y me gustaría mostrar su contenido de cierta manera. Quiero "filas", y cada fila puede mostrar no más de tres "objetos", por falta de una palabra mejor. Así que quiero iterar sobre la matriz y crear mi HTML en el proceso. Mi idea es esta: cada "primero de tres" elementos en la matriz debería abrir la "fila". Cada "tercero de tres" elementos debe cerrar la "fila". Sin embargo, si el último elemento de la matriz [interna] no es el "tercero de tres", aún debe cerrar la fila. Así, por ejemplo, si tuviéramos algo así como L=[ [0,1,2,3,4], [5,6,7] ], me gustaría mostrarlo así:

0 1 2 
3 4 

5 6 7 

que podría ser marcado como:

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

Lo primero que pensé fue utilizar simplemente el operador de módulo y ver si cada iteración fue la "primera", "segunda" o "tercera" de una fila, pero las plantillas de Django no son compatibles directamente con el módulo (más sobre esto más adelante).

Así me ocurrió con código de la plantilla de esta manera:

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

y esto fue un buen comienzo. Tomando el ejemplo anterior, en 0 abriríamos un div, en 1 no hacemos nada, en 2 cerramos el div, en 3 lo abrimos, y en 4 ... bueno, no cerraría, porque 4 no era el "tercer en una serie de 3 ". Entonces, aunque las plantillas de Django no tienen módulo, sí tienen una marca divisible por by, así que se me ocurrió una lógica adicional para decir, si tocamos el último elemento del bucle for [interno], y tampoco es divisible por 3 (por lo que no tenemos un cierre duplicado), a continuación, cierre el div:

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

Esto funcionó mejor! Ahora, pasé por toda la primera matriz interna con el marcado adecuado. Mi problema es este: aparentemente, la funcionalidad del ciclo de Django no se restablece cuando sales del alcance del ciclo for interno. Lo que esto significa es que mi número 5 del ejemplo anterior no abre un div como debería, no se reconoce como el primero en un ciclo. De hecho, en realidad está siendo reconocido como un tercero, por lo que está cerrando un div.

Así que no estoy seguro de a dónde ir desde aquí. Esto parece ser un known and unfixed issues in Django. ¿Alguien puede ayudar, por favor?

tl; dr Quiero tomar una matriz de 2d, p. L=[ [0,1,2,3,4], [5,6,7] ] y debidamente marcar hasta agrupación no más de 3 a la vez y sin agrupar todos los elementos de varias matrices de juntas, así:

0 1 2 
3 4 

5 6 7 

¿Cuál sería el código de la plantilla para eso y por qué?

Respuesta

14

Usted debe ser capaz de utilizar {% if forloop.counter0|divisibleby:"3" %} para determinar cuándo abrir la etiqueta <div> y {% if forloop.last or forloop.counter|divisibleby:"3" %} para determinar cuándo cerrar la etiqueta </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

Perfecto, gracias! – Joseph

Cuestiones relacionadas