Django QuerySet с исключением и аннотацией без возврата результатов - PullRequest
2 голосов
/ 10 ноября 2011

Исходя из этого ТАКОГО вопроса о подсчете поддельных ключей , у меня проблема. Это мои модели:

class Type(models.Model):
  is_bulk = models.BooleanField()

class Component(models.Model):
  parent = models.ForgeinKey(Type, related_name="components")

Я хочу написать набор запросов, который имеет все типы, кроме тех, которые имеют is_bulk = True и не имеют компонентов. Если is_bulk = False, его следует включить. Если is_bulk = True и у вас есть 1+ связанных компонентов, то вы включены. Если нет, вы исключены.

Исходя из ответа, я попробовал этот набор запросов:

Type.objects.annotate(num_components=Count('components')).exclude(is_bulk=True, num_components=0)

Но результат не возвращается.

Однако это означает, что должны быть результаты:

>>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
[(False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0)]

Все объекты типа имеют is_bulk = False, и все они имеют 0 компонентов. При чтении документации .exclude (…) это должно быть NOT(is_bulk=True AND num_components=0), что должно быть True для каждого типа. Правильно? (Я сделал здесь недоразумение, если так, каков правильный набор запросов)

Если нет, то почему этот набор запросов возвращает [], когда он должен вернуть их все? Это ошибка в Django 1.3?

Ответы [ 2 ]

1 голос
/ 14 ноября 2011

Я исправил это, изменив набор запросов на:

types_qs.annotate(num_components=Count('components')).filter(Q(is_bulk=False) | (Q(is_bulk=True) & Q(num_components__gt=0)))

Это работает, но я не могу понять, почему мой оригинальный не сделал. Ах, хорошо.

0 голосов
/ 10 ноября 2011

Я попробовал этот пример, и вам нужно объявить related_name в вашей области:

class Component(models.Model):
    parent = models.ForgeinKey(Type, related_name='components')

Это должно сделать это

UPDATE

На основании вашего примера:

>>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
[(False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0), (False, 0)]

И мой:

>>> [(x.is_bulk, x.num_components) for x in Type.objects.annotate(num_components=Count('components'))]
[(False, 3), (False, 0), (False, 1), (False, 4), (True, 2), (True, 3), (True, 1), (True, 1), (False, 2), (True, 7), (True, 0), (False, 0)]

Я предполагаю, что у вас нет объектов с требованиями вашего набора запросов:

Type.objects.annotate(num_components=Count('components')).exclude(is_bulk=True, num_components=0)

Ваши результаты:

[]

Вот результаты в моем случае:

[<Type: Type object>, <Type: Type object>, <Type: Type object>, <Type: Type object>]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...