Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

420
Vistas
Custom TruncFunc in Django ORM

I have a Django model with the following structure:

class BBPerformance(models.Model):
    marketcap_change = models.FloatField(verbose_name="marketcap change", null=True, blank=True)
    bb_change = models.FloatField(verbose_name="bestbuy change", null=True, blank=True)
    created_at = models.DateTimeField(verbose_name="created at", auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name="updated at", auto_now=True)

I would like to have an Avg aggregate function on objects for every 3 days.
for example I write a queryset that do this aggregation for each day or with something like TruncDay function.

queryset = BBPerformance.objects.annotate(day=TruncDay('created_at')).values('day').annotate(marketcap_avg=Avg('marketcap_change'),bb_avg=Avg('bb_change')

How can I have a queryset of the aggregated value with 3-days interval and the index of the second day of that interval?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

I guess it's impossible on DB level (and Trunc is DB level function) as only month, days weeks and so on are supported in Postgres and Oracle.

So what I would suggest is to use TruncDay and then add python code to group those by 3 days.

over 4 years ago · Santiago Trujillo Denunciar

0

The following should work, although it's slightly ugly.

If you get the difference in days between each row's date and the min date you can then take the Mod of this difference to work out how many days you need to shift to get "middle" date. This middle date can then be grouped on using a values query

import datetime
from django.db.models import F, IntegerField, Avg, Min, DurationField, DateField
from django.db.models.functions import Cast, Mod, Extract

BBPerformance.objects.order_by(
    'created_at'
).annotate(
    diff=F('created_at__date') - BBPerformance.objects.aggregate(min=Min('created_at__date'))['min']
).annotate(
    diff_days=Cast(Extract('diff', 'days'), output_field=IntegerField())
).annotate(
    to_shift=Mod('diff_days', 3) - 1
).annotate(
    grouped_date=Cast(F('created_at__date') - Cast(F('to_shift') * datetime.timedelta(days=1), output_field=DurationField()), output_field=DateField())
).order_by(
    'grouped_date'
).values(
    'grouped_date'
).annotate(
    marketcap_avg=Avg('marketcap_change'),
    bb_avg=Avg('bb_change')
)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda