0

我有一个“对话”经理,看起来像这样:

class AnnotationManager(models.Manager):
def get_query_set(self):
    return super(AnnotationManager, self).get_query_set().annotate(
        num_votes=Count('vote', distinct=True),
        num_comments=Count('comment', distinct=True),
        num_commentators = Count('comment__user', distinct=True),
    )

投票和评论有一个外键到对话框。评论对用户有一个外键。当我这样做时:

dialogs_queryset = Dialog.public.filter(organization=organization)
dialogs_popularity = dialogs_queryset.exclude(num_comments=0) | dialogs_queryset.exclude(num_votes=0)

...dialogs_popularity 永远不会返回组合,而只会返回超过 0 条评论的对话框,或者如果我更改 OR 的顺序,则返回超过 0 票的对话框!

对我来说,预期的行为将是获得超过 0 票的对话和超过 0 条评论的对话。

我错过了什么?还是这里的注释行为有错误?

4

1 回答 1

0

想要带有投票和评论的对话吗?

# must have both a vote and a comment
# aka.  has_comments_and_votes = has_comments AND has_votes
#                              = !(has_no_comments OR has_no_votes)
has_comments = ~Q(num_comments=0)
has_votes = ~Q(num_votes=0)

dialogs_queryset.filter(num_comments__ne=0, num_votes__ne=0)
# or with Q objects
dialogs_queryset.filter(has_comments & has_votes)
dialogs_queryset.exclude(~has_comments | ~has_votes)

或具有投票、评论或两者的对话。(根据评论您想要什么。)

# must have at least 1 vote or 1 comment
# aka. has_comments_or_votes = has_comments OR has_votes
#                            = !(has_no_comments AND has_no_votes)
dialogs_queryset.exclude(num_comments=0, num_votes=0)
# again with Q objects
dialogs_queryset.filter(has_comments | has_votes)  # easiest to read!
dialogs_queryset.exclude(~has_comments & ~has_votes)

我添加了Q 对象示例,因为“|” 在您的代码示例中似乎暗示了它们,它们使创建 ORed 查询变得更加容易。

编辑:我添加了has_comments并使has_votes事情更容易阅读。

于 2010-03-09T23:13:01.777 回答