Django按周几进行分组?

6

我正在使用Django 1.5.1和Python 3.3.x,无法使用原始查询。

有没有一种方法可以得到一个按周日分组的QuerySet,对于使用日期__range过滤器的QuerySet?我正在尝试按周日分组结果,对于范围在任何两个日期之间的查询(可以相差一年)。我知道如何获取符合星期几的行,但这将需要使用7个查询来查找每个星期几的数据。

我已经尝试通过使用__week_day过滤器来找出不同方法,但什么都不起作用。甚至Google搜索也没有帮助,这让我怀疑是否可能做到。这里有没有Django大师知道如何实现,如果可以的话?

4个回答

11

由于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


经过五个版本的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日(今天)之间的记录,您将看到所有这些记录。如果您添加了更多日期为明天或下周一等的记录,则不会看到这些记录。

如果您想要其他日期的记录,只需输入相应的日期即可。

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

希望这有所帮助! :D

这只是一个日期范围,而不是分组。当日期范围跨越多个星期时,它将无法工作。 - Zamphatta
我认为这相当于 Model.objects.filter(date__week=week_number),多个星期你是指连续的吗? - Victor Castillo Torres

0
你需要在选择中添加一个额外的工作日字段,然后按照该字段进行分组求和或平均值聚合。请注意,这将成为一个特定于数据库的查询,因为“额外”符号将被传递到DB选择语句中。
给定模型:
class x(models.Model):
    date = models.DateField()
    value = models.FloatField()

然后,对于MySQL,使用ODBC工作日到Python日期时间工作日的映射:
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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接