Poll.objects.filter(), возвращающий несколько экземпляров одного и того же опроса

Следуя учебнику в djangoproject, я создал опрос с двумя опросами.

In [14]: Poll.objects.all()
Out[14]: [<Poll: poll1>, <Poll: poll2>]

Когда я применяю фильтр

In [18]: Poll.objects.filter(choice__choice_text__isnull=False)

Возвращается следующее, хотя есть только 2 опроса.

Out[18]: [<Poll: poll1>, <Poll: poll1>, <Poll: poll1>, <Poll: poll2>, <Poll: poll2>, <Poll: poll2>]

Почему есть несколько случаев одного и того же опроса? Цель фильтра - отфильтровать опросы, которые не имеют выбора. Кроме того, другие фильтры, как показано ниже, работают.

In [19]: Poll.objects.filter(pub_date__lte=timezone.now)
Out[19]: [<Poll: poll1>, <Poll: poll2>]

1 ответ

Решение

Есть ли у возвращаемых опросов выбор? Похоже, что он возвращает один экземпляр опроса для каждого связанного выбора, что приводит к дублированию. Чтобы избавиться от них, используйте distinct():

Poll.objects.filter(choice__choice_text__isnull=False).distinct()

Обновление: поехали под капот. Ваш первый запрос охватывает отношение Poll-Choice, используя закулисное JOIN для "объединения" двух таблиц. (СОЕДИНЕНИЯ могут быть сложными, поэтому, если это сбивает с толку, я предлагаю исследовать их.) Ваш запрос возвращает объект опроса для каждого варианта, текст которого равен нулю.

С другой стороны, ваш второй запрос просто выбирается из таблицы опроса. Линия:

Poll.objects.filter(pub_date__lte=timezone.now)

переводит на SELECT * FROM poll WHERE pub_date <= tz.now, Для получения более подробной информации о полевых поисках см. Документацию. Для получения дополнительных указаний по связующим отношениям, смотрите документы снова.

Другие вопросы по тегам