【发布时间】:2016-02-22 09:08:48
【问题描述】:
如何使用 Django ORM 通过相关项的条件 聚合对查询集中的所有对象进行排序? Django 1.8 及更高版本明确具有conditional aggregation support,我需要 Django 的答案。这显然会涉及 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)
用户拥有聊天群,其他用户可以访问该聊天群。要回答的问题是:如何生成所有组的排序列表,以便按每个组在最近 60 个中看到的唯一流量排序分钟?在过去 60 分钟内看到大量唯一身份访问者的组会排在顶部,此类流量几乎为零(或零)的组会出现在列表底部。
这是一个条件聚合问题,因为从本质上讲,我们需要为每个组对象注释过去 60 分钟内记录的所有相关的、唯一的组流量对象的计数。
有人可以告诉我如何使用 Django ORM 来解决 = 1.8(感谢this),我不想通过原始或额外的 SQL 查询来实现。
【问题讨论】:
-
通过唯一流量,我的意思是如果它是具有相同 ID 的访问者,则不会重复计算。 IE。在 Django ORM 中使用
distinct。 -
到目前为止您尝试过哪些查询?
-
大名单人,等一下,我会放一些最接近的。
-
查询1:这个没有考虑过去60分钟的流量:
groups = Group.objects.annotate(views=Count('grouptraffic__visitor', distinct=True))。 -
查询 2:这些没有考虑到所有组:date =
datetime.now()-timedelta(hours=1)new_traff = GroupTraffic.objects.filter(time__gte=date, which_group__private='0').distinct('visitor').values_list('id',flat=True)trendingGrp_ids = GroupTraffic.objects.filter(id__in=new_traff).values('which_group').annotate(total=Count('which_group')).order_by('-total')trendingGrps = [Group.objects.filter(id=grp['which_group']).extra(select={"views":grp['total']})[0] for grp in trendingGrp_ids]return trendingGrps
标签: python django sorting django-queryset django-orm