Agrupando fechas en Django

Mi pregunta es casi exactamente la misma que esta publicación , excepto que estoy usando Python y Django en lugar de PHP.

La tarea es tomar:

id date 1 2009-01-01 10:15:23 2 2009-01-01 13:21:29 3 2009-01-02 01:03:13 4 2009-01-03 12:20:19 5 2009-01-03 13:01:06 

Y salida:

 2009-01-01 1 2 2009-01-02 3 2009-01-03 4 5 

Puedo hackear manualmente algo juntos repasando las fechas ordenadas y generando HTML en una cadena en mi archivo de vista de Python, pero me pregunto: ¿hay una mejor manera de usar una plantilla de Django o una función de Python ingeniosa?

Puede resolver esto con los templatetags reagrupar y fechar .

 {% regroup object_list by start_date|date:"Ymd" as objects_by_day %} {% for d in objects_by_day %} ### DO SOMETHING HERE {% endfor %} 

itertools.groupby es tu querido, querido amigo:

 import itertools dates = [ (1,'2009-01-01 10:15:23'), (2,'2009-01-01 13:21:29'), (3,'2009-01-02 01:03:13'), (4,'2009-01-03 12:20:19'), (5,'2009-01-03 13:01:06'), ] for key,group in itertools.groupby(dates, key=lambda x: x[1][:11]): print key for element in group: print ' ', element 

El código anterior imprime lo siguiente:

 2009-01-01 (1, '2009-01-01 10:15:23') (2, '2009-01-01 13:21:29') 2009-01-02 (3, '2009-01-02 01:03:13') 2009-01-03 (4, '2009-01-03 12:20:19') (5, '2009-01-03 13:01:06') 

Al realizar informes en conjuntos de datos más grandes, itertools.group_by puede ser demasiado lento. En esos casos hago postgres manejar la agrupación:

 truncate_date = connection.ops.date_trunc_sql('day','timestamp') qs = qs.extra({'date':truncate_date}) return qs.values('date').annotate(Sum('amount')).order_by('date') 

Todas estas son respuestas razonables si el OP podría usar python en el código de la plantilla. (Y en esa cuenta, preferiría la solución itertools.groupby ()). Pero no puedes usar python en el código de la plantilla. En el mejor de los casos, escribiría un templatetag que realizó esta operación. Y ya hay un templatetag que hace esto.

Para hacer la agrupación en Django dentro de la plantilla, use reagrupar :

 {% regroup people by gender as gender_list %} 
    {% for gender in gender_list %}
  • {{ gender.grouper }}
      {% for item in gender.list %}
    • {{ item.first_name }} {{ item.last_name }}
    • {% endfor %}
  • {% endfor %}

Ejemplo levantado de la documentación de Django reagrupar . reagrupar está disponible en django 0.96 , 1.0 y 1.1 , al menos.

Si me diera una idea de lo que se pasa a la plantilla, podría hackear un ejemplo que utiliza sus datos.

Además, hay una publicación en el blog en la que DjangoGrrl funciona exactamente a través de esta pregunta.

Esto sería más fácil si utilizara las funciones de formato de fecha de su base de datos para eliminar los tiempos (en la selección). A continuación, puede agrupar por la columna formateada (utilizando un alias de columna).

Después de eso, puedes usar un bucle con un poco de lógica para transponer los resultados a lo que deseas. Todavía no he usado el sistema de plantillas de django, pero así es como se vería la lógica en Python:

 >>> rows = [(1,'2009-01-01'), (2,'2009-01-01'), (3, '2009-02-02'), \ (4, '2009-02-02'), (5, '2009-02-02')] >>> topdate = None >>> for r in rows: ... if topdate <> r[1]: ... topdate = r[1] ... print r[1] ... print r[0] ... 2009-01-01 1 2 2009-02-02 3 4 5 

Debe haber una forma directa de convertir esto al código de la plantilla de django.