Django QuerySet Filtering - Пересечь предложение в полевых поисках? - PullRequest
0 голосов
/ 09 октября 2019

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

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    choices = models.ManyToManyField('Choice')

class Choice(models.Model):
    choice_text = models.CharField(max_length=200)

Теперь предположим, что у меня есть QuerySet, состоящий из объектов выбора, назовите его universe_choices. Я хочу отфильтровать все объекты Вопросов, чтобы получить только те Вопросы, выбор которых имеет хотя бы один общий элемент с universe_choices. Другими словами, если хотя бы один из choices Вопроса также находится в universe_choices, включите этот Вопрос в QuerySet, возвращенный из моего фильтра.

В идеале я хотел бы сделать это с чем-то эквивалентным:

Question.objects.filter(choices__intersection__exists=universe_choices)

или

Question.objects.filter(choices.intersection(universe_choices).exists())

Но очевидно, что ни методы intersection(), ни exists() не существуют вlookup-form, и вы не можете использовать их как есть в фильтрующем запросе.

Есть ли способ сделать это?

Конечно, неэффективный обходной путь состоит в том, чтобы перебрать все объекты Вопроса и проверить, есть ли пересечение между каждымQuestion.choices объект итерации и universe_choices.

1 Ответ

0 голосов
/ 09 октября 2019

Вы можете получить это очень просто с помощью этого:

Question.objects.filter(choices__in=universe_choices)

См. https://docs.djangoproject.com/en/2.2/ref/models/querysets/#in (Документация не описывает и не дает примеров того, как это происходит, когдалевая часть __in является многозначной, но я определенно использовал ее для идентичного варианта использования, и она работала как нужно.)

...