Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Group By Weekday?

I'm using Django 1.5.1, Python 3.3.x, and can't use raw queries for this.

Is there a way to get a QuerySet grouped by weekday, for a QuerySet that uses a date __range filter? I'm trying to group results by weekday, for a query that ranges between any two dates (could be as much as a year apart). I know how to get rows that match a weekday, but that would require pounding the DB with 7 queries just to find out the data for each weekday.

I've been trying to figure this out for a couple hours by trying different tweaks with the __week_day filter, but nothing's working. Even Googling doesn't help, which makes me wonder if this is even possible. Any Django guru's here know how, if it is possible to do?

like image 784
Zamphatta Avatar asked Jun 22 '13 19:06

Zamphatta


2 Answers

Since extra is deprecated, here is a new way of grouping on the day of the week using ExtractDayOfWeek.

from django.db.models.functions import ExtractWeekDay
YourObjects.objects
    .annotate(weekday=ExtractWeekDay('timestamp')) 
    .values('weekday')                          
    .annotate(count=Count('id'))                  
    .values('weekday', 'count')   

This will return a result like:

[{'weekday': 1, 'count': 534}, {'weekday': 2, 'count': 574},.......}

It is also important to note that 1 = Sunday and Saturday = 7

like image 157
Turtle Avatar answered Sep 28 '22 14:09

Turtle


Well man I did an algorithm this one brings you all the records since the beginning of the week (Monday) until today

for example if you have a model like this in your app:

from django.db import models

class x(models.Model):
        date = models.DateField()

from datetime import datetime
from myapp.models import x
start_date = datetime.date(datetime.now())
week = start_date.isocalendar()[1]
day_week =start_date.isoweekday()
days_quited = 0
less_days = day_week
while less_days != 1:
     days_quited += 1
     less_days -= 1

week_begin = datetime.date(datetime(start_date.year,start_date.month,start_date.day-days_quited))

records = x.objects.filter(date__range=(week_begin, datetime.date(datetime.now())))

And if you add some records in the admin with a range between June 17 (Monday) and June 22 (today) you will see all those records, and if you add more records with the date of tomorrow for example or with the date of the next Monday you will not see those records.

If you want the records of other week unntil now you only have to put this:

start_date = datetime.date(datetime(year, month, day))
records = x.objects.filter(date__range=(week_begin, datetime.date(datetime.now())))

Hope this helps! :D

like image 39
Victor Castillo Torres Avatar answered Sep 28 '22 14:09

Victor Castillo Torres