Saltar al contenido

Django, ¿cómo agrupar modelos por fecha?

Nuestros programadores estrellas agotaron sus provisiones de café, por su búsqueda todo el tiempo por la resolución, hasta que Patricia halló el resultado en GitLab y hoy la compartimos con nosotros.

Solución:

El ORM en sí no puede devolver la lista de modelos, pero puede usar itertools.groupby para este propósito, suponga que primero ordena el conjunto de datos en el nivel de la base de datos.

from itertools import groupby
from operator import attrgetter

from django.db.models.functions import TruncDate

queryset = MyModel.objects.annotate(
    created_at_date=TruncDate('created_at'),
).order_by('created_at')
groupedset = groupby(queryset, attrgetter('created_at_date'))

A continuación, podrá iterar sobre groupedset usando

for date, objects in groupedset:
    ...

Puedes probar el siguiente código:

samples = MyModel.objects.all()
result = 
for sample in samples:
    date_string = sample.created_at.strftime("%m.%d.%Y")
    if date_string in result:
        result[date_string].append(sample)
    else:
        result[date_string] = [sample]

Devolverá una salida como la siguiente:


'06.07.2020': [],
'05.07.2020': [, ]

Básicamente, lo que hace es primero buscar todas las filas y luego agruparlas a nivel de python en un diccionario.

Me temo que actualmente esto no es completamente posible, al menos que yo sepa (sin algunas modificaciones realmente profundas dentro del ORM de Django).

Sin embargo, lo que puede hacer es realizar conversiones de fechas y agregaciones dentro de la base de datos:

Este ejemplo asume que su base de datos soporta el to_char función.

qs = MyModel.objects.all()
qs.annotate(
  created_at_date=models.Func(
    models.F('created_at'),
    models.Value("'dd.MM.yyyy'"),
    function='to_char',
  )
).values('created_at_date').aggregate(
    # do required aggregations like Count or Sum
)

[edit] algunas correcciones + como bryan60 señaló correctamente, también puede usar Trunc:

from django.db.models.functions import Trunc
MyModel.objects.all().annotate(
    created_at_trunc=Trunc('created_at', 'day', output_field=models.DateTimeField())
).values('created_at_trunc')

Aquí tienes las reseñas y valoraciones

Tienes la opción de patrocinar nuestro quehacer fijando un comentario y dejando una valoración te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *