#django #filter #many-to-many #field
#django #Фильтр #многие ко многим #поле
Вопрос:
Я постараюсь изо всех сил описать, что я пытаюсь здесь сделать. У меня есть 3 класса:
- Вопрос
- Тип вопроса
- QuestionTemplate
И отношения являются:
- Вопрос <-ManyToMany-> questionType
- QuestionTemplate <-ManyToMany-> questionType
Итак, запрос находится в методе внутри QuestionTemplate, который выдает мне список возможных вопросов с тем же типом questionType, которые связаны с QuestionTemplate.
Я пробовал: questions = Question.objects.filter(type__in = template.type.all())
Где «template» — это объект QuestionTemplate. Но этот запрос возвращает мне вопросы, у которых есть хотя бы один questionType внутри списка questionType из шаблона. Что я хочу сделать, так это получить точно такие же типы вопросов как в вопросе, так и в шаблоне.
Я много чего перепробовал, но не могу заставить это работать, пожалуйста, кто-нибудь, спасите меня!
Комментарии:
1. пожалуйста, уточните, что вы пытаетесь получить. Вы пытаетесь получить вопросы, которые в точности совпадают в …? Я думаю, вы пропустили пару слов из своего первоначального сообщения.
2. Я хочу получить вопросы, которые имеют одинаковые (точно) связи с questionType в заданном QuestionTemplate. Итак, если я получу шаблон, содержащий questionType = (Type1, Type2 и Type3) Запрос вернул бы все вопросы, которые имеют связи с questionType = (Type1, Type2, Type3). Таким образом, любой другой вопрос, который имеет другую связь с questionType, например (Type1, Type2 и Type5), не войдет в список.. То же самое относится к одному вопросу, который имеет QuestionTypes = (Type1 и Type2), поскольку в нем нет Type3, подобного шаблону, он также будет удален.
Ответ №1:
types = template.type.all()
query = Question.objects
for t in types:
query = query.filter(type = t)
questions = []
for q in query.select_related('type'):
ok = True
for t in q.type.all():
if t not in types:
ok = False
break
if ok:
questions.append(q)
save_questions_in_m2m_relations_so_that_you_dont_have_to_repeat_this(questions)
Довольно неуклюжий, но должен делать то, что вам нужно.
Комментарии:
1. Говоря о производительности, лучше ли это делать только с помощью filter / exclude вместо итерации по списку, проверяя, какое из них в порядке?
2. @Arruda: Filter /exclude выполняет все вычисления в базе данных, так что это всегда быстрее, часто в десять раз. Но я не мог придумать решение в чистом filter / exclude. Возможно, вы могли бы сделать это в raw SQL. Но прежде чем проводить оптимизацию , убедитесь, что это на самом деле узкое место в производительности. Может сэкономить вам много времени, если это не так.
3. Основная причина, по которой я хочу это знать, заключается в том, что я хочу научиться решать подобную проблему … это решение хорошо подошло бы к проблеме, с которой я сталкиваюсь сейчас, но, возможно, в будущем я столкнусь с другой проблемой, которая может быть решена только с помощью запросов, поэтому я хотел знать, как это сделать таким образом.