2010-03-09 58 views
0

我有一个“Dialog”的经理看起来像这样:Django:注释后合并查询集的问题

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), 
    ) 

投票和评论有一个ForeignKey to Dialog。注释有一个ForeignKey用户。当我这样做:

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条评论的对话框。

我错过了什么?或者注释行为中是否存在错误?

回答

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 objects的例子,因为“|”在您的代码示例中似乎暗示了他们,并且它们使创建ORed查询变得更加容易。

编辑: 我加了has_commentshas_votes使事情更容易阅读。

+0

它看起来已经颠倒了你的代码块及其描述。 – 2010-03-10 01:23:19

+0

我在每个代码块的描述中增加了更多内容。请再看一看,并更详细地说明如何反转描述。谢谢。 – istruble 2010-03-10 04:22:08

+0

谢谢。为了澄清我正在寻找具有选票,评论或两者的对话。我试过你的代码,但它仍然不起作用。 dialogs_queryset.filter(num_comments__ne = 0,num_votes__ne = 0) ...给我没有投票和没有评论的对话框。 dialogs_queryset.exclude(num_comments = 0,num_votes = 0) ...给我带有评论和投票的对话。 代码的行为并不像我期望的那样,当我对注释值执行此操作时! – 2010-03-12 14:46:23