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
, Для получения более подробной информации о полевых поисках см. Документацию. Для получения дополнительных указаний по связующим отношениям, смотрите документы снова.