Django-按一列分组(使用计数)

时间:2019-06-16 21:03:47

标签: python django

我想得到这样的效果

SELECT "restApi_comment"."id", "restApi_comment"."text", "restApi_comment"."movie_id", COUNT("restApi_comment"."id") AS "count" FROM "restApi_comment" GROUP BY  "restApi_comment"."movie_id" ORDER BY "count" DESC

但是django是基于此的

obj = Comment.objects.annotate(count=Count('movie_id')).order_by('-count')

给我

SELECT "restApi_comment"."id", "restApi_comment"."text", "restApi_comment"."movie_id", COUNT("restApi_comment"."id") AS "count" FROM "restApi_comment" GROUP BY "restApi_comment"."id", "restApi_comment"."text", "restApi_comment"."movie_id" ORDER BY "count" DESC

问题在于分组不是基于一列(movie_id),而是基于三列(id,text,movie_id)。

[models.py]

class Comment(models.Model):
    text = models.CharField(max_length=50, blank=True)
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)

我尝试过这种方法

obj=Comment.objects.values('movie_id').annotate(count=Count('movie_id')).order_by('-count').values('movie_id', 'text')

这给了我这样的效果,并且没有返回所有列

SELECT "restApi_comment"."movie_id", COUNT("restApi_comment"."movie_id") AS "count" FROM "restApi_comment" GROUP BY "restApi_comment"."movie_id" ORDER BY "count" DESC

2 个答案:

答案 0 :(得分:0)

results = []
movies = Movie.objects.distinct()
for movie in movies:
    results.append('name': movie.name, 'total_comments':Comment.objects.filter(movie=movie).count()) 

results是一个包含两个值的字典列表,一个是键name,用于区分结果。第二个值是键total_comments,这是用.filter()

查询的电影有多少评论的计数

这样您就可以在模板中执行以下操作:

{% for movie in movies %}
    # some layout html with your data in it
{% endfor %}

希望这会有所帮助:)

答案 1 :(得分:0)

我根据您的要求使用了此models.py进行测试。

from django.db import models


class Movie(models.Model):
    title = models.TextField()

    def __str__(self):
        return self.title


class Comment(models.Model):
    movie = models.ForeignKey(
        Movie, 
        related_name='comments',
        on_delete=models.CASCADE,
    )
    text = models.TextField()

虽然注释计数似乎是您最关心的问题,但获得Movie对象的列表并为其注释计数添加注释(并按其排序)意味着从Movie模型开始,例如(从Django aggregation doc中拉出):

Movie.objects.annotate(count=Count('comments')).order_by('-count')

测试用例的部分输出,以显示总体和结果:

>>> from django.db.models import Count
>>> from movies.models import Movie, Comment
>>> 
>>> for title, comment_count in (
...     ('The Meg', 32), 
...     ('Citizen Kane', 126), 
...     ('Meet the Feebles', 1),
...     ('Dellamorte Dellamore', 900),
... ):
...     m = Movie(title=title)
...     m.save()
...     for i in range(comment_count):
...         Comment(movie=m, text=i).save()
... 
>>> for m in Movie.objects.annotate(count=Count('comments')).order_by('-count'):
...     print(m, m.count)
... 
Dellamorte Dellamore 900
Citizen Kane 126
The Meg 32
Meet the Feebles 1