2012-08-15 28 views
14

necesito para representar la colección en la plantilla y envolver cada cuatro elementos de laplantillas de Django {% for%} etiqueta complemento li cada elemento cuarta

<li></li> 

La plantilla debe ser como este:

<ul> 
    <li> 
     <a></a> 
     <a></a> 
     <a></a> 
     <a></a> 
    </li> 
    <li> 
     <a></a> 
     <a></a> 
     <a></a> 
     <a></a> 
    </li> 
    <li> 
     <a></a> 
     <a></a> 
     <a></a> 
     <a></a> 
    </li> 
</ul> 

así que tengo que hacerlo en el {% for%}

{% for obj in objects %} 
{#add at 1th and every 4th element li wrap somehow#} 
    <a>{{object}}</a> 
{# the same closing tag li#} 
{% endfor %} 

Respuesta

47

Lo que sigue debe resolver su problema, utilizando una función de etiquetas de plantilla:

<ul> 
    <li> 
    {% for obj in objects %} 
     <a>{{ obj }}</a> 

    {# if the the forloop counter is divisible by 4, close the <li> tag and open a new one #} 
    {% if forloop.counter|divisibleby:4 %} 
    </li> 
    <li> 
    {% endif %} 

    {% endfor %} 
    </li> 
</ul> 
+0

Realmente no me gusta esta forma de procedimiento de inyectar etiquetas de cierre cuando se cumple una condición. Consulte la respuesta http://stackoverflow.com/a/11965885/636626 para obtener una solución mucho más legible y reutilizable. –

+0

@NilsWerner: Depende de si la solución es aplicable al caso de uso o no. Si la solución de Hedde requiere que modifique una gran cantidad de código y/o infraestructura existente, podría ser más factible continuar con la "ruta más fácil" de tratar con una lista plana en comparación con un objeto generador. Además, la responsabilidad de cuántos elementos se agrupa la lista se ha transferido a la persona que llama. Si esta es la forma deseada o no depende del caso de uso.Dicho esto, estoy de acuerdo en que es deseable luchar por plantillas más limpias y soluciones reutilizables. – Manuzor

3

puede utilizar divisibleby filtro incorporado, here is link to django documentation

así que algo como esto funcionaría

{% if value|divisibleby 4 %} 
#your conditional code 
{% endif %} 
1

yo personalmente consideraría para separar los elementos de la vista antes de pasarlos a la plantilla y luego utilizando bucles for anidados. Excepto que realmente solo tienes la opción de filtro o plantilla como mencionó Vaibhav Mishra.

+0

Si esos 4 objetos en realidad no pertenecen juntos en primer lugar, su enfoque acoplaría la lógica más estrechamente a la representación visual. Los diseñadores y programadores deberían poder trabajar por separado, este es uno de los objetivos de django después de todo. – Manuzor

+1

Los marcos, como Django, están diseñados para ajustarse a las necesidades de uno, si es necesario agrupar los objetos en imo, está perfectamente bien hacerlo dentro de la capa de visualización. Sin duda, si hace la vida del diseñador más fácil. P.ej. la clasificación también se realiza fuera de la capa de la plantilla, por lo general. –

+0

@Hedde Estoy de acuerdo con, parcialmente. Sin embargo, es posible que no pueda agrupar estos objetos por algo que tengan en común como un conjunto fijo de 4 (por ejemplo, una lista simple de nombres). El diseñador podría aspirar a una representación más compacta de los datos para el usuario. Sin embargo, si los datos deben estar agrupados en todo momento ** porque pertenecen juntos ** (por ejemplo, la matriz se parece a [nombre0, apellido0, dirección0, teléfono0, nombre1, ..., nombreN, ..]) entonces, de hecho esto debería hacerse en la capa de vista. Al menos así entiendo la separación de la vista (programador) y la plantilla (diseñador). – Manuzor

13

Usted puede utilizar la etiqueta divisibleby como se ha mencionado antes, pero a efectos de compensación de la plantilla por lo general prefieren una función auxiliar que devuelve un generador :

def grouped(l, n): 
    for i in xrange(0, len(l), n): 
     yield l[i:i+n] 

ejemplo visión simplista:

from app.helpers import grouped 

def foo(request): 
    context['object_list'] = grouped(Bar.objects.all(), 4) 
    return render_to_response('index.html', context) 

plantilla de ejemplo:

{% for group in object_list %} 
    <ul> 
     {% for object in group %} 
      <li>{{ object }}</li> 
     {% endfor %} 
    </ul> 
{% endfor %} 
+0

¡Simplemente brillante! Esta es, por lejos, la solución más simple, limpia y fácil de leer. +1 –

+0

Gracias esto es brillante – Cody

0

si desea trabajar con la comprobación primera y última forloop forloop que podría utilizar esto:

<ul> 
{% for obj in objects %} 
{% if forloop.first %} 
    <li> 
{% endif %} 
     <a>{{obj}}</a> 
{% if forloop.counter|divisibleby:4 and not forloop.first %} 
    </li> 
    <li> 
{% endif %} 
{% if forloop.last %} 
    </li> 
{% endif %} 
{% endfor %} 
</ul> 
Cuestiones relacionadas