django 在两列上的非重复之后获取一列的计数

pgx2nnw8  于 2022-12-14  发布在  Go
关注(0)|答案(2)|浏览(125)

以下是我的模型的简化表示:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    template_id = models.IntegerField(null=True)
    ...

我想做的是显示一个模板被用户使用的次数。所以当我列出模板的时候,我希望能够说Used by X users。主要的吸引力是我不想只计算一个用户一次(所以如果一个用户使用一个模板两次,他们仍然算作“一个用例”)。所有stackoverflow的帖子都在谈论这样做:

counts = Post.objects.all().values("template_id").order_by().annotate(count=Count("template_id"))

但是很明显,如果用户使用同一个模板两次,那么这会导致用户重复计数。我可以对template_iduser配对做如下区分:

Post.objects.all().values("template_id", "user__id").distinct()
# Printing this out, I get 2 distinct entries in the QuerySet:
# <QuerySet [{'template_id': 1, 'user__id': 1}, {'template_id': 1, 'user__id': 2}]>

然而,当我试图获得template_id的计数(下面的代码)时,它似乎忽略了distinct,并且仍然对用户进行了双重计数。

Post.objects.all().values("template_id", "user__id").distinct().values("template_id").annotate(count=Count("template_id"))
# Printing this out I get `count` = 3, which double counts a user.
# <QuerySet [{'template_id': 1, 'count': 3}]>

不管怎样,我写了一个快速测试用例,这就是失败的地方。

user1 = baker.make("User")
user2 = baker.make("User")

# Populate posts
quest1 = baker.make("post.Post", user=user1, template_id=1)
quest2 = baker.make("post.Post", user=user1, template_id=1)  # Duplicate shouldn't count
quest3 = baker.make("post.Post", user=user2, template_id=1)
brccelvz

brccelvz1#

使用Django内置的ORM,通过以下操作使其工作:

template_ids = []  # My templates

        # Get the number of times each template_id was used.
        top_template_counts = (
            Post.objects.filter(template_id__in=template_ids)
            .values("template_id")  # groups by template ids
            .annotate(user_count=Count("user", distinct=True))  # Gets the number of users using each template
            .order_by("-user_count")
        )

        # Accessing `top_template_counts` 
        for template_id_count in top_template_counts[:10]:
            template_id = template_id_count["template_id"]
            count = template_id_count["parent_count"]
hwamh0ep

hwamh0ep2#

为什么不用途:

counts = Post.objects.all().values("template_id", "user__id").distinct().values("template_id").count()

相关问题