El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Django regroup

He fet quatre cosetes al programari del blog, per tal de mirar de passar al màxim la validació del w3c, encara tenc problemes amb els pre que em genera el markdown dins paràgrefs i que no passen la validació, però al manco ara la plana es veu prou bé amb Konqueror.

Fent neteja m'he trobat amb la necessitat de refer la jerarquia de l'històric d'apunts. No era gens neta i com que ara el blog té un menú prou potent, he decidit posar molta cosa que estava al lateral com a opció del desplegable.

Per fer la jerarquia d'articles el que es ja el primer de tot és obtenir la llista d'arxius. Això ho feim cridant un tag creat ad-hoc pel blog

{% get_yearly_archive as archive_list %}

que el que fa és executar

Entry.objects.current_active().dates('pub_date', 'month', order='DESC')

i posar-ho a una variable que pot ser usada a la plantilla.

Amb aquest tag obtenim la llista de mesos en els que hi hem fet apunts. Un element d'aquest llista és per exemple:

datetime.datetime(2008, 2, 1, 0, 0)

Com podem veure és un tipus datetime de python i com a tal podem obtenir-ne fàcilment l'any objecte.year o el mes objecte.month.

El que volem, com dic, és fer una jerarquia, és a dir, tenir una cosa com:

  • 2009
  • Abril 2009
  • Març 2009
  • 2008
  • Desembre 2008

Això normalment duria força feina, però és aquí quan hom veu que Django està pensat per als reptes de la vida real, ja ve amb un template tag predefinit que ens permet fer agrupacions, el regroup

Donada una llista ordenada regroup ens crea una estructura de dades que contindrà els elements pels quals volem fer el grup i dins aquests els element de la llista que tenen aquest element.

En el nostre cas hem posat l'historial dins una variable anomenada archive_list, que recordem és una llista de datetime. Farem

{% regroup archive_list by year as historial_list %}

Amb això hem creat la nostra estructura de dades. Fixem-nos que l'exemple que duu la documentació de Django diu que regroup té com a paràmetre una llista de diccionaris. És part de la gràcia del tipat feble, pel que fa al funcionament de la funció l'estructura datetime es comporta com espera l'iterador groupby que és el que fa servir internament.

Podem simular-ho perfectament a la consola de iPython

>In [43]: p = itertools.groupby (x, lambda z: z.year) 
>In [44]: for i in p:
> ....: print i[0]
> ....: for j in i[1]:
> ....: print j

Ja tenim l'estructura de dades, així que ara sols quedar recorre i presentar la informació tal com la volem. Per això cal tenir en compte que la nostra estructura defineix la variable grouper que fa referència al valor del camp pel qual estam fent l'agrupació

{% for year in historial_list %} 
<li>
<span class="dir">{{year.grouper }}</span>
<ul>
{% for d in year.list %}
<li>
<a href="{% setting "BLOG_ROOT" %} {{ year.grouper }}/{{d|date:"m" }}/'class="menu_content">
{{ d|date:"M Y" }}
</a>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}

Com és habitual, és més llarg d'explicar que de fer.

blog comments powered by Disqus