假设我有一个简单的论坛模型:
class User(models.Model):
username = models.CharField(max_length=25)
...
class Topic(models.Model):
user = models.ForeignKey(User)
...
class Post(models.Model):
user = models.ForeignKey(User)
...
现在说我想查看用户子集的每个用户有多少主题和帖子(例如,他们的用户名以“ab”开头)。
所以如果我为每个帖子和主题做一个查询:
User.objects.filter(username_startswith="ab")
.annotate(posts=Count('post'))
.values_list("username","posts")
Yeilds:
[('abe', 5),('abby', 12),...]
和
User.objects.filter(username_startswith="ab")
.annotate(topics=Count('topic'))
.values_list("username","topics")
收率:
[('abe', 2),('abby', 6),...]
HOWEVER ,当我尝试注释两个以获得一个列表时,我得到一些奇怪的东西:
User.objects.filter(username_startswith="ab")
.annotate(posts=Count('post'))
.annotate(topics=Count('topic'))
.values_list("username","posts", "topics")
收率:
[('abe', 10, 10),('abby', 72, 72),...]
为什么主题和帖子成倍增加?我期待这个:
[('abe', 5, 2),('abby', 12, 6),...]
获得正确列表的最佳方法是什么?
答案 0 :(得分:89)
我认为Count('topics', distinct=True)
应该做正确的事。这将使用COUNT(DISTINCT topic.id)
代替COUNT(topic.id)
来避免重复。
User.objects.filter(
username_startswith="ab").annotate(
posts=Count('post', distinct=True)).annotate(
topics=Count('topic', distinct=True)).values_list(
"username","posts", "topics")
答案 1 :(得分:1)
尝试在上一个查询集中添加distinct:
User.objects.filter(
username_startswith="ab").annotate(
posts=Count('post')).annotate(
topics=Count('topic')).values_list(
"username","posts", "topics").distinct()
有关详细信息,请参阅https://docs.djangoproject.com/en/1.3/ref/models/querysets/#distinct,但基本上您将获得重复的行,因为注释跨越多个表。