如何通过相关项的条件聚合对 Django 查询集进行排序?

How to sort a Django queryset by a conditional aggregation of related items?

如何使用 Django ORM 通过 条件 相关项目的聚合对查询集中的所有对象进行排序? Django 1.8 及更高版本明确具有 conditional aggregation support,我需要 Django < 1.8 的答案。这显然会涉及 3 或 4 个查询。以下是回答者可以用来说明她的回答的示例模型:

class Group(models.Model):
    owner = models.ForeignKey(User)
    created_at = models.DateTimeField(auto_now_add=True)

class GroupTraffic(models.Model):
    visitor = models.ForeignKey(User)
    which_group = models.ForeignKey(Group)
    time_of_visit = models.DateTimeField(auto_now_add=True)

用户拥有自己的聊天群,其他用户可以访问该聊天群。要回答的问题是:如何生成 all 组的排序列表,使其按每个组在其中看到的 unique 流量排序最后 60 分钟?在过去 60 分钟内看到大量独立访客的​​组被排在顶部,此类流量几乎为零(或零)的组出现在列表底部。

这是一个条件聚合问题,因为从本质上讲,我们需要为每个组对象注释过去 60 分钟内记录的所有相关的、唯一的组流量对象的计数。

有人可以告诉我如何使用 Django ORM 解决 < 1.8 的这个问题吗?我已经知道如何通过条件聚合(感谢 )为 >=1.8 做到这一点,我不想通过原始或额外的 SQL 查询来做到这一点。

只需过滤 time_of_visit,它应该可以正常工作:

one_hour_ago = datetime.now()-timedelta(hours=1)
recent_groups = Group.objects.filter(grouptraffic__time_of_visit>=one_hour_ago)
visitors = recent_groups.annotate(views=Count('grouptraffic__visitor', distinct=True))

然后获取所有较旧的组,并为空视图提供 extra 字段:

older_groups = Group.objects.filter(grouptraffic__time_of_visit < one_hour_ago).extra(select={'visits':0})

然后用管道将它们连接在一起:

all_groups = visitors | older_groups