Как проверить, имеет ли объект ссылку ManyToMany в наборе запросов django?
У меня есть эти модели в моем проекте django
class Question(models.Model):
heading = models.CharField(max_length=300)
description = models.TextField()
class Profile(models.Model):
name = models.CharField(max_length=100,null=False,blank=False)
completed = models.ManyToManyField(Question)
Я пытаюсь найти оптимизированный способ получения списка вопросов для пользователя, который должен содержать информацию о том, выполнил он его или нет. Я думаю, это можно сделать с помощью этих наборов вопросов:-
all_questions = Question.objects.all()
completed_questions = Question.objects.filter(profile = profile_instance)
, где profile_instance
- объект профиля. Затем мы можем перебрать all_questions
и проверить, существуют ли они также в completed_questions
, но я не уверен, оптимизировано ли это для пагинации. Я использую Django-Rest Framework pagination.
Редактирование 1:-. Похоже, что я не совсем понимаю, какой результат мне нужен, я расскажу об этом подробнее. Мне нужен набор запросов, который удовлетворяет двум требованиям:-
- Список всех вопросов.
- В этом списке, если, допустим, вопрос 1 завершен пользователем, то в нем должно быть поле boolean, установленное в true. Обратите внимание, что вопрос будет выполнен только для текущего зарегистрированного пользователя, а не для всех пользователей.
Если вы просто пытаетесь подключить вопросы к профилю, то подойдет что-то вроде этого:
completed_questions = profile.completed.all()
Это вернет набор вопросов Question
объектов, связанных с этим профилем. В этом случае нет необходимости просматривать все вопросы на предмет их наличия в завершенных вопросах.
Если вы хотите отфильтровать вопросы, чтобы получить все те, на которые есть (или нет) ответы, вы можете отфильтровать профили с завершенными вопросами и затем отфильтровать вопросы по ним:
profile_with_completed = Profile.objects.exclude(completed=None)
completed_questions = Question.objects.filter(profile__in=profile_with_completed)
Редактировать
Чтобы получить список всех вопросов с указанием того, был ли вопрос завершен пользователем или нет, используйте следующую аннотацию. Она проверит, есть ли первичный ключ каждого вопроса в списке первичных ключей завершенных вопросов, связанных с выбранным профилем (который можно отдельно связать с вошедшим пользователем).
from django.db.models import Case, When, Value, BooleanField
all_questions = Question.objects.annotate(is_complete=Case(
When(
pk__in=profile.completed.values('pk'),
then=Value(True)
),
default=Value(False),
output_field=BooleanField())
)
В вашем представлении или шаблоне вы можете получить доступ к question.is_complete
, который возвращает true или false.