Agrupar por fecha

39 views
Skip to first unread message

Marcelo A. Robin

unread,
Nov 2, 2022, 8:24:44 AM11/2/22
to Django-es
Hola muchachos... sigo con el dilema de mostrar en el aside, y su agrupación por meses y años. Osea en mi aside quiero mostrar algo como:

Octubre de 2022
Agosto de 2022
Julio de 2022
...
Enero de 2021

Probe algunas sugerencias que me dieron, pero no supe implementarlas de acuerdo a lo que estoy haciendo. Todo el aside lo estoy cargando desde un archivo processors.py con un procesador de contexto, que lo que me permite es hacer las consultas una única vez. 
Por lo tanto se me ha ocurrido hacerlo a mano y he hecho lo siguiente:

def ctx_dic_history(request):
       ctx_history = {}
       ctx_history['dates'] = Post.objects.values('created').distinct()
       return ctx_history

y si en el aside pongo {{ dates }} 

me devuelve lo siguiente:

<QuerySet [{'created': datetime.datetime(2022, 10, 20, 14, 27, 54, 306946, tzinfo=datetime.timezone.utc)}, {'created': datetime.datetime(2022, 10, 19, 15, 3, 5, 120145, tzinfo=datetime.timezone.utc)}, {'created': datetime.datetime(2022, 9, 19, 15, 1, 42, 922290, tzinfo=datetime.timezone.utc)}, {'created': datetime.datetime(2022, 8, 19, 15, 0, 56, 558949, tzinfo=datetime.timezone.utc)}, {'created': datetime.datetime(2022, 7, 19, 15, 0, 5, 562106, tzinfo=datetime.timezone.utc)}, {'created': datetime.datetime(2022, 7, 19, 14, 47, 25, 455669, tzinfo=datetime.timezone.utc)}]>

el tema que al ser un campo datetime me los toma todos como distintos... y yo quiero que solo lo haga por año y mes... 

Cómo puedo recorrer ese queryset para capturar esos valores y mostrarlos por pantalla ?

Marcelo Robin

unread,
Nov 2, 2022, 9:23:00 AM11/2/22
to djan...@googlegroups.com
leyendo la documentación de django encontré algo mas ajustado a mi problema... y conseguí ajustar un poco más el resultado:

def ctx_dic_history(request):
ctx_history = {}
ctx_history['dates'] = Post.objects.dates('created','month').distinct()
return ctx_history

ya me devuelve algo más razonable en el aside:

4 <QuerySet [datetime.date(2022, 7, 1), datetime.date(2022, 8, 1), datetime.date(2022, 9, 1), datetime.date(2022, 10, 1)]>

por lo menos ya me devuelve lo que estoy queriendo... ahora me falta recorrer ese queryset... 
cómo accedo a cada item ?



--
--
Ha recibido este mensaje porque está suscrito a Grupo "Grupo de Usuarios del Framework Django de habla hispana" de Grupos de Google.
Si quieres publicar en este grupo, envía un mensaje de correo
electrónico a djan...@googlegroups.com
Para anular la suscripción a este grupo, envíe un mensaje a django-es-...@googlegroups.com
Para obtener más opciones, visita este grupo en http://groups.google.com.bo/group/django-es.
---
Has recibido este mensaje porque estás suscrito al grupo "Django-es" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a django-es+...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/django-es/09c2c6ad-a0a1-4139-b902-9e26406218cen%40googlegroups.com.

Gonzalo V

unread,
Nov 3, 2022, 4:26:45 PM11/3/22
to djan...@googlegroups.com
for r in  Post.objects.dates('created','month').distinct():
.. etc
Saludos,
Gonzalo


Marcelo Robin

unread,
Nov 4, 2022, 6:56:21 AM11/4/22
to djan...@googlegroups.com
Mi, no entender 

Francisco Pandol

unread,
Nov 4, 2022, 7:31:11 PM11/4/22
to djan...@googlegroups.com
Marcelo, ya tenés en el template todas las fechas que querés, no? En la variable dates del context. Para recorrer ese array tenés que poner en el template del aside algo asi
{% for element in dates %}
  {{ element }}
{% endfor %}

Si querés darle otro formato a la fecha podés usar el templatetag "date"  https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#date



--
Francisco Pandol

Iago Otero

unread,
Nov 5, 2022, 4:30:23 AM11/5/22
to djan...@googlegroups.com
Hola... Llego tarde al hilo..

Existen un tipo de views.. Como YearArchiveView... Que ayudan en ese proceso..

No las he usado..pero las he visto en la documentación



Hernán Gastón

unread,
Nov 5, 2022, 6:07:25 AM11/5/22
to djan...@googlegroups.com
Para recorrer un queryset y por ejemplo armar una lista con todas las instancias distintas podes hacer un set, que solo se carga con objetos repetidos ejemplo:
para esto 
ctx_history['dates'] = Post.objects.values('created').distinct()
podes hacer:
ctx_history['dates'] = list(set([obj.values for obj in Post.objects.all()]))

te comento paso a paso:
la funcion list -> devuelve una lista
la funcion set -> crea un set (es como una lista pero de objetos irrepetibles)
dentro del set -> hay una lista por comprension [es todo lo que esta en corchetes]

Es decir dentro del ctx te queda una lista que despues la podes recorrer con un for en la template:
{% for obj in dates %}
{{ obj }} -> si queres le podes poner un filter para mostrar solo año y mes
{ % endfor %}

espero haber sido de ayuda perdon la demora saludos!!

Marcelo Robin

unread,
Nov 5, 2022, 8:29:36 AM11/5/22
to djan...@googlegroups.com
Hola Iago, fue el primer tema que abordé gracias al aporte de Carlos, pero no pude adaptar mi caso porque esto lo estoy construyendo desde un context processor. Por lo que vi, necesitas pasar por parametro a esas vistas un año dado. Y no es exactamente mi caso que quiero un listado de los posts agrupados por mes y año... Gracias igual por la sugerencia... 

El sáb, 5 nov 2022 a la(s) 05:30, Iago Otero (iago.o...@gmail.com) escribió:

Marcelo Robin

unread,
Nov 5, 2022, 8:44:38 AM11/5/22
to djan...@googlegroups.com
Logré hacer esto en la vista... 

{% for item in dates %}
<li>
<a href={% url 'dates' %}>{{ item.month }} de {{ item.year }}</a>
</li>
{% endfor %}

esto me muestra en la vista, lo siguiente:

  1. 10 de 2022
  2. 9 de 2022
  3. 8 de 2022
  4. 7 de 2022
  5. probé hacer lo siguiente:
{{ item.month|date:"F" }} de {{ item.year }}
pero el resultado es:
  1. de 2022
  2. de 2022
  3. de 2022
  4. de 2022
es decir que no funciona el filtro de fecha date... 

la otra opcion es crear un if anidado que analice cada mes devuelto y concatenar una cadena de texto 
tipo una cosa asi y ahí sí funciona bien... pero me duelen los ojos de pensar poner 12 condicionales ahi: 

{% if item.month == 10 %}
<a href={% url 'dates' %}>Octubre de {{ item.year }}</a>
{% endif %}


Marcelo Robin

unread,
Nov 5, 2022, 8:55:17 AM11/5/22
to djan...@googlegroups.com
variable = list(set([obj.values('created').distinct() for obj in Post.objects.all()]))

Probe esto pero no funciona

AttributeError at /

'Post' object has no attribute 'values'



Hernán Gastón

unread,
Nov 5, 2022, 4:48:15 PM11/5/22
to djan...@googlegroups.com
perdon quizas si me pasas el modelo de Post te puedo ayudar mejor igualmente el método distinct estaria demas ejemplo:
variable = list(set([obj for obj in Post.objects.all() if obj.created==True]))

en este caso supongo que created es un booleano, entonces la lista por comprension va a traer todos los post created==True y como están en un set solo se agregan los que son distintos y a eso lo convierto en lista..

Marcelo Robin

unread,
Nov 6, 2022, 6:23:03 PM11/6/22
to djan...@googlegroups.com
No, el campo created, es un campo datetimefield

class Post(models.Model):
title = models.CharField(max_length=250, verbose_name='Título')
excerpt = models.TextField(verbose_name='Bajada')
#content = models.TextField(verbose_name='Contenido')
content = RichTextField(verbose_name='Contenido')
image = models.ImageField(upload_to='posts', null=True, blank=True, verbose_name='Imagen')
published = models.BooleanField(default=False, verbose_name='Publicado')

# Campos con relaciones
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='get_posts', verbose_name='Categoría')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='get_posts', verbose_name='Autor')
tags = models.ManyToManyField(Tag, verbose_name='Etiquetas')

created = models.DateTimeField(auto_now_add=True, verbose_name='Fecha de creación')
updated = models.DateTimeField(auto_now=True, verbose_name='Fecha de modificación')

carlos

unread,
Nov 6, 2022, 7:05:50 PM11/6/22
to djan...@googlegroups.com

Hernán Gastón

unread,
Nov 6, 2022, 8:03:17 PM11/6/22
to djan...@googlegroups.com
Listo entonces proba así
variable = list(set([obj.created for obj in Post.objects.all()]))

Te va a devolver una lista con todas las fechas que tienen los objetos sin repetir

Reply all
Reply to author
Forward
0 new messages