Как проверить, имеет ли объект ссылку 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. Список всех вопросов.
  2. В этом списке, если, допустим, вопрос 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.

Вернуться на верх