Django ORM 按问题分组计数

Django ORM count group by issue

我有以下型号:

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')

[Referral: Referral object, Referral: Referral object, Referral: Referral object, Referral: Referral object, Referral: Referral object, Referral: Referral object]

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

有什么想法吗?

使用 reverse relationships 应该可以实现您想要做的事情。由于您在 recipient 键上使用了 related_name,因此假设您从以下查询集开始:

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 中分组,但好消息是您仍然可以仅使用一个数据库查询来完成此操作。