Sistema de plantillas de Django: ¿Cómo resuelvo este bucle / agrupación / recuento?
-
08-07-2019 - |
Pregunta
Tengo una lista de artículos, y cada artículo pertenece a una sección.
class Section(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
class Article(models.Model):
section = models.ForeignKey(Section)
headline = models.CharField(max_length=200)
# ...
Quiero mostrar los artículos, agrupados por sección.
Sponsorships, Advertising & Marketing 1. Nike To Outfit All 18 Univ. Of Memphis Athletic Teams 2. Phil Jackson Questions Harrah's Signage At New Orleans Arena 3. Puma Hires N.Y.-Based Ad Agency Droga5 To Lead Global Account 4. Pizza Patrón To Replace Pizza Hut As AAC Exclusive Provider 5. Marketplace Roundup Sports Media 6. Many Patriots Fans In New England Will Not See Tonight's Game 7. ESPN Ombudsman Says Net Should Have Clarified Holtz Situation 8. EA Sports To Debut Fitness Title For Nintendo Wii In Spring '09 9. Blog Hound: Rockets-Suns Scuffle Today's No.1 Topic 10. Media Notes Leagues & Governing Bodies 11. DEI, Chip Ganassi Racing To Merge Into Four-Car Sprint Cup Team 12. NASCAR Roundtable Part II: New Strategies, Cutbacks Discussed 13. Average Ticket Price For NFL Playoff Games To Drop By 10%
Descubrí cómo hacer la mayor parte con el sistema de plantillas de Django.
{% regroup articles by section as articles_by_section %}
{% for article in articles_by_section %}
<h4>{{ article.grouper }}</h4>
<ul>
{% for item in article.list %}
<li>{{ forloop.counter }}. {{ item.headline }}</li>
{% endfor %}
</ul>
{% endfor %}
Simplemente no puedo entender cómo hacer los números. El código anterior numera los artículos en Sports Media 1-5 en lugar de 6-10. ¿Alguna sugerencia?
Solución
Siguiendo la sugerencia de Jeb en un comentario, creé un etiqueta de plantilla personalizada .
Reemplacé {{forloop.counter}}
con {% counter%}
, una etiqueta que simplemente imprime cuántas veces se ha llamado.
Aquí está el código para mi etiqueta de contador.
class CounterNode(template.Node):
def __init__(self):
self.count = 0
def render(self, context):
self.count += 1
return self.count
@register.tag
def counter(parser, token):
return CounterNode()
Otros consejos
Esto no es exactamente bueno, pero puede ser apropiado para alguien:
{% for article in articles %}
{% ifchanged article.section %}
{% if not forloop.first %}</ul>{% endif %}
<h4>{{article.section}}</h4>
<ul>
{% endifchanged %}
<li>{{forloop.counter}}. {{ article.headline }}</li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
Creo que puede usar forloop.parentloop.counter dentro del bucle interno para lograr la numeración que busca.
Podría usar una lista ordenada en lugar de desordenada:
{% regroup articles by section as articles_by_section %}
<ol>
{% for article in articles_by_section %}
<h4>{{ article.grouper }}</h4>
{% for item in article.list %}
<li>{{ item.headline }}</li>
{% endfor %}
{% endfor %}
</ol>