2013-06-22 96 views
3

我正在使用Django 1.5.1,Python 3.3.x,并且无法对此使用原始查询。Django Group By Weekday?

有没有一种方法可以获得按工作日分组的QuerySet,对于使用日期__range过滤器的QuerySet?我试图按工作日对结果进行分组,查询范围介于任何两个日期之间(可能相隔多达一年)。我知道如何get rows that match a weekday,但这需要用7个查询来敲打数据库才能找出每个工作日的数据。

我一直试图通过尝试使用__week_day过滤器的不同调整来解决这个问题,但没有任何工作。即使谷歌搜索没有帮助,这让我怀疑这是否甚至可能。如果有可能的话,任何Django guru的知道如何?

回答

3

由于extra已被弃用,这里是使用ExtractDayOfWeek的星期几分组的新方法。

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

这将返回类似结果:

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

同样重要的是要注意,1 =星期天和星期六= 7

+0

后来有5个版本的django,添加了'ExtractWeekDay'关键字。注意:仍然需要在django 1.5中使用.extra()函数(如问题所述)。 – tmarthal

1

好男人,我做了一个算法,这个给你带来自本周(周一)开始,直到所有的记录,今天

例如,如果你在你的应用程序是这样一种模式:

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()))) 

如果你在6月17日(星期一)和6月22日(今天)之间的范围内添加一些记录,你会看到所有这些记录,并且如果你添加更多的记录,例如明天的日期或日期下周一你不会看到这些记录。

如果你想一周的unntil现在记录你只有把这个:

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

希望这有助于! :D

+0

这虽然只是一个日期范围,而不是一个分组。当日期范围跨越多个星期时,它将不起作用。 – Zamphatta

+0

嗯,我认为这相当于'Model.objects.filter(date__week = week_number)', 你的意思是连续几个星期? –

0

您需要为选区添加一个额外的星期几字段,然后按总和或平均聚合进行分组。请注意,这会成为特定于数据库的查询,因为'额外'符号将传递给DB select语句。

鉴于型号:

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

然后,针对MySQL的,与ODBC平日对蟒蛇日期时间平日的映射:

x.objects.extra(select={'weekday':"MOD(dayofweek(date)+5,7)"}).values('weekday').annotate(weekday_value=Avg('value'), weekday_value_std=StdDev('value')) 

请注意,如果你不需要转换MySql ODBC工作日(1 =星期日,2 =星期一...)到python工作日(星期一是0,星期日是6),那么你不需要做模数。

0

对于模型是这样的:

class A(models.Model): 
    date = models.DateField() 
    value = models.FloatField() 

您可以使用查询:

weekday  = {"w": """strftime('%%w', date)"""} 
qs = A.objects.extra(select=weekday).values('w').annotate(stat = Sum("value")).order_by()