2010-03-09 39 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