2010-03-09 2 views
0

У меня есть менеджер для «Диалога», глядя, как это:Джанго: проблема с объединением querysets после аннотации

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 к диалогу. Комментарии имеют 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.

EDIT: Я добавил has_comments и has_votes, чтобы сделать чтение немного проще.

+0

Кажется, вы изменили свои блоки кода и их описания. –

+0

Я добавил больше к описанию каждого блока кода. Пожалуйста, взгляните еще раз и дайте более подробную информацию о том, как описание будет отменено. Спасибо. – istruble

+0

Спасибо. Чтобы очистить, я искал диалоги, имеющие либо голоса, либо комментарии, либо и то, и другое. Я пробовал ваш код, и он все еще не работает. dialogs_queryset.filter (num_comments__ne = 0, num_votes__ne = 0) ... дает мне диалоги без голосов и без комментариев. dialogs_queryset.exclude (num_comments = 0, num_votes = 0) ... дает мне диалоги с комментариями и голосами. Код просто не ведет себя так, как я ожидаю, когда я делаю это по аннотированным значениям! –

Смежные вопросы