Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by weeks, months, days

Tags:

django

I would like to group querysets by a date interval according to a datetime attribute of the model. I want to show average values from the model on a day-to-day, week-by-week and month-by-month basis.

E.g.

  • Week commencing 01/01/2017 - average distance: 30
  • Week commencing 08/01/2017 - average distance: 40 ...

Can this be achieved with the standard Django queryset API?

like image 967
zubhav Avatar asked Feb 09 '17 22:02

zubhav


People also ask

How do I group data by month in Excel?

Right-Click on any cell within the Dates column and select Group from the fly-out list. Then select Month in the dialog box. Using the Starting at: and Ending at: fields, you can even specify the range of dates that you want to group if you don't want to group the entire list.

Why can't i group dates by month in a pivot table?

If even one of the cells contains invalid data, the grouping feature will not be enabled. Pivot Table won't allow you to group dates and you will get a cannot group that selection error. So, the ideal step would be to look for those cells and fix them!


2 Answers

Assuming the following model which might match your description

class Activity(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True, blank=True)
    distance  = models.IntegerField()

You can achieve a week by week statistic with the following query

from django.db.models.functions import ExtractWeek, ExtractYear
from django.db.models import Sum, Count

stats = (Activity.objects
    .annotate(year=ExtractYear('timestamp'))
    .annotate(week=ExtractWeek('timestamp'))
    .values('year', 'week')
    .annotate(avg_distance=Avg('distance'))
)

Sample output

<QuerySet [{'year': 2018, 'week': 31, 'distance': 3.2}]>

To recover the first day of week, check Get date from week number

In particular:

for record in stats:
    week = "{year}-W{week}-1".format(year=record['year'], week=record['week'])
    timestamp = datetime.datetime.strptime(week, "%Y-W%W-%w")
like image 185
Andrei Cioara Avatar answered Sep 24 '22 23:09

Andrei Cioara


There are a bunch of field lookups specifically for date/datetime fields: week, day, month (should be combined with year) etc.

like image 38
Marat Avatar answered Sep 25 '22 23:09

Marat