Django按小时组

时间:2015-05-26 17:21:02

标签: python django orm group-by

我在Django中有以下模型。

class StoreVideoEventSummary(models.Model):
    Customer = models.ForeignKey(GlobalCustomerDirectory, null=True, db_column='CustomerID', blank=True, db_index=True)
    Store = models.ForeignKey(Store, null=True, db_column='StoreID', blank=True, related_name="VideoEventSummary")
    Timestamp = models.DateTimeField(null=True, blank=True, db_index=True)
    PeopleCount = models.IntegerField(null=True, blank=True)

我想知道每小时进入商店的人数。

为实现这一目标,我尝试按Timestamp上的小时对行进行分组,并将PeopleCount列加起来。

store_count_events = StoreVideoEventSummary.objects.filter(Timestamp__range=(start_time, end_time),
                                                       Customer__id=customer_id,
                                                       Store__StoreName=store)\
        .order_by("Timestamp")\
        .extra({
            "hour": "date_part(\'hour\', \"Timestamp\")"
        }).annotate(TotalPeople=Sum("PeopleCount"))

这似乎不按小时对结果进行分组,它只是向查询集中的每一行添加一个新列TotalPeople,其值与PeopleCount相同。

3 个答案:

答案 0 :(得分:6)

将其分为两步

objs = StoreVideoEventSummary.objects.filter(Timestamp__range=(start_time, end_time),
                                                   Customer__id=customer_id,
                                                   Store__StoreName=store)\
    .order_by("Timestamp")

def date_hour(timestamp):
   return datetime.datetime.fromtimestamp(timestamp).strftime("%x %H")

groups = itertools.groupby(objs, lambda x:date_hour(x.Timestamp))
#since groups is an iterator and not a list you have not yet traversed the list
for group,matches in groups: #now you are traversing the list ...
    print group,"TTL:",sum(1 for _ in matches)

这允许您按几个不同的标准进行分组

如果您只想要小时而不管日期,只需更改date_hour

def date_hour(timestamp):
   return datetime.datetime.fromtimestamp(timestamp).strftime("%H")

如果您想按星期几分组,只需使用

def date_hour(timestamp):
   return datetime.datetime.fromtimestamp(timestamp).strftime("%w %H")

答案 1 :(得分:1)

建立原始代码,您可以尝试:

store_count_events = StoreVideoEventSummary.objects.filter(Timestamp__range=(start_time, end_time), Customer__id=customer_id, Store__StoreName=store)\
    .extra({
        "hour": "date_part(\'hour\', \"Timestamp\")"
    })\
    .values("hour")\
    .group_by("hour")\
    .annotate(TotalPeople=Sum("PeopleCount"))

答案 2 :(得分:1)

我知道我已经迟到了,但是从文档https://docs.djangoproject.com/en/1.11/ref/models/querysets/#django.db.models.query.QuerySet.extra

中提取线索

以下过滤器应该适合您。

store_count_events = StoreVideoEventSummary.objects.filter(
    Timestamp__range=(start_time, end_time),
    Customer__id=customer_id,
    Store__StoreName=store
).order_by(
    'Timestamp'
).extra(
    select={
        'hour': 'hour(Timestamp)'
    }
).values(
    'hour'
).annotate(
    TotalPeople=Sum('PeopleCount')
)