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

投票とコメントには、Dialog への ForeignKey があります。コメントには、ユーザーへの 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 を超えるコメントを含むダイアログを取得することです。

私は何が欠けていますか?または、ここで注釈の動作にバグがありますか?

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_commentsandを追加しました。has_votes

于 2010-03-09T23:13:01.777 に答える