在Django中,如何通过单个查询获取基于唯一字段值的总行数?

2 投票
2 回答
2054 浏览
提问于 2025-04-18 05:08

这个情况看起来很常见,所以我希望有人能给我一个快速的答案。

想象一下,我有多个网站,每个网站下有多个公司,我正在收集潜在客户的信息。于是我有一个潜在客户表,每条记录都有以下几个字段:日期网站公司(一个潜在客户可以对应多个公司)、用户评论。现在我需要生成一个汇总,显示每个公司在每个网站上每个日期获得的潜在客户总数。

所以,简单来说,我需要一个查询,能让我看到每个公司在每个网站上的总记录数。这能在一个查询中实现吗?

另外,我们也可以很容易地遍历这些网站,这样的话,我们只需要计算每个公司在特定网站下的记录数。

感谢任何想法。这里有一个可以用来参考的示例模型:

class Lead(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    site = models.ForeignKey(Site)
    companies = models.ManyToManyField(Company)
    user = models.ForeignKey(User)
    comment = models.TextField()

2 个回答

2

你可以使用 distinct 这个查询集方法。

Lead.objects.distinct('companies', 'site', 'date').count()

你可以把任何字段(或者多个字段)传给 distinct,这样就能得到该行中不重复的记录。然后你只需要简单地调用 count 方法就可以了。

3

我最近在研究这个问题,觉得我找到了一个能得到我想要结果的解决方案。根据上面的模型,我使用了以下代码:

Lead.objects.values('site', 'companies').annotate(Count('id'))

这段代码会生成一个字典列表,每个字典代表一个独特的网站和公司组合,每个字典里有一个 id__count 的键,记录了这个特定网站和公司组合的总行数。如果一个线索关联了多个公司,那么每个公司都会生成一个单独的字典。

在我们的实际模型中,我们还有不同类型的线索,并且增加了一个 type 字段。所以如果我想把这个考虑进去,我只需要在模型中添加一个 type 字段,然后使用以下代码:

Lead.objects.values('site', 'companies', 'type').annotate(Count('id'))

这样的话,我就能得到每个网站、每种类型、每个公司的一个字典,每个字典都有自己的计数。Django 真是聪明!

总之,这可能是个基础问题,但我没找到相关的解答。希望这能帮助到某些人。

撰写回答