Django ORM按问题分组

时间:2017-06-19 15:00:43

标签: python django postgresql django-models django-orm

我有以下型号:

class Referral(models.Model):
    referrer = models.ForeignKey(Profile, related_name='referral_made')
    recipient = models.ForeignKey(
        Profile, related_name='referral_received')
    created_at = models.DateTimeField(auto_now=True)

我需要按每个收件人

的推介数量进行分组

此查询有效:

Referral.objects.values('recipient_id').annotate(total_referral=Count('recipient_id')).order_by('-total_referral')

,输出

  

[{'total_referral':5,'recipient_id':929},{'total_referral':1,   'recipient_id':143}]

问题是我需要查询对象供以后使用

如果我删除了“.values('recipient_id')”,我会分开记录,而不是分组。

Referral.objects.annotate(total_referral=Count('recipient_id')).order_by('-total_referral')
  

[推荐人:推荐对象,推荐人:推荐对象,推荐人:   推荐对象,推荐:推荐对象,推荐:推荐   对象,推荐:推荐对象]

我已经进行了大量搜索并测试了一些答案,但无法将结果作为查询对象

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

应该可以使用reverse relationships来实现您尝试做的事情。由于您已使用related_name密钥上的recipient,因此我们假设您从以下查询集开始:

profiles = Profile.objects.prefetch_related('referral_received').all()

当您循环遍历此查询集中的每个对象时,该个人资料收到的推介将可用(无需任何其他查询,因为我们已使用上面的prefetch_related),如下所示:

groups = []
for each_profile in profiles:
    group_qs = each_profile.referral_received.all()
    groups.append({
        "recipient_id": each_profile.id,
        "total_referral": len(group_qs), 
        "queryset": group_qs,
    })

请注意,如果您不使用prefetch_related,那么将在每次循环迭代中触发一个单独的查询,这将最终导致您花费相当多的I / O等待时间,具体取决于个人资料的数量。

尽管这种方法避免了数据库层分组而支持在python中进行分组,但好消息是你仍然只能使用一个数据库查询来实现这一点。