Django – Agrupar por parte de fecha solo

MyModel.objects.filter(created_at__gte='2011-03-09', created_at__lte='2011-03-11').values('created_at','status').annotate(status_count=Count('status')) 

La consulta anterior tiene el problema con el campo de fecha created_at hora created_at . ¿Es posible ajustar la consulta anterior para ignorar el valor de la hora y usar solo el valor de la fecha mientras se realiza la agrupación?

No estoy seguro de si el ORM de Django puede realizar una conversión de tiempos de datos a fechas en medio de una consulta. Sin embargo, primero puede hacer la consulta, obtener los resultados y luego usar la función groupby() Python para ordenar las filas que se devuelven. Aquí hay un pequeño ejemplo de agrupación de fechas de datos por fecha:

 from pprint import pprint from datetime import datetime from itertools import groupby rows = [('Frodo party', datetime(3018, 9, 22, 10, 38)), ('Nazgul defeat Rangers', datetime(3018, 9, 22, 11, 57)), ('Frodo finishes packing', datetime(3018, 9, 23, 10, 59)), ('Gandalf tames Shadowfax', datetime(3018, 9, 23, 13, 11)), ('Gandalf crosses the Isen', datetime(3018, 9, 24, 18, 46))] for key, values in groupby(rows, key=lambda row: row[1].date()): print('-') pprint(key) pprint(list(values)) 

Como puede ver, tiene que proporcionar groupby() con una función key que tome uno de los objetos que está agrupando y extraiga el valor por el que debería tener lugar la agrupación; en este caso, toma el segundo elemento de cada fila. con [1] y luego llama a la datetime método datetime Python date() para extraer la parte de la fecha sin las horas y los minutos. La salida de la secuencia de comandos tiene este aspecto (la función pprint() es solo una statement de “impresión” elegante que sangra la salida, ¡no será necesaria en tu código Django!):

 - datetime.date(3018, 9, 22) [('Frodo party', datetime.datetime(3018, 9, 22, 10, 38)), ('Nazgul defeat Rangers', datetime.datetime(3018, 9, 22, 11, 57))] - datetime.date(3018, 9, 23) [('Frodo finishes packing', datetime.datetime(3018, 9, 23, 10, 59)), ('Gandalf tames Shadowfax', datetime.datetime(3018, 9, 23, 13, 11))] - datetime.date(3018, 9, 24) [('Gandalf crosses the Isen', datetime.datetime(3018, 9, 24, 18, 46))] 

Soy demasiado tarde para esta pregunta, pero para futuras referencias, quiero señalar que esto es realmente posible con Django nativo, como se describe en https://stackoverflow.com/a/2283913

Sí, eso es posible mediante el uso de funciones de formato de fecha ‘extra’ y de nivel de base de datos. La implementación se puede encontrar en, por ejemplo, el paquete django-qsstats-magic .

Puedes hacerlo fácilmente usando la palabra clave extra en django.

 MyModel.objects .filter(created_at__gte='2011-03-09', created_at__lte='2011-03-11') .extra({"created_at":"date_trunc('day', created_at)"}).values('created_at','status').annotate(status_count=Count('status')) 

date_trunc es la función postgres que toma, solo se especifica la precisión.