Исключая одну строку из отношений ManytoMany в Django - PullRequest
0 голосов
/ 11 июня 2018

Это мой объект пользователя,

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, max_length=255)
    mobile = PhoneNumberField(null=True)
    username = models.CharField(null=False, unique=True, max_length=255)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

А это мой объект викторины,

class Quiz(Base):
    category = models.ForeignKey(Category, related_name='quizzes', on_delete=models.CASCADE)
    players = models.ManyToManyField(User)

Это фильтр, который я использую для поиска тестов определенной категории.что пользователь не играл,

quiz = Quiz.objects.filter(category=category).exclude(players=user).order_by('created')[:1]

Но исключение является списком и, следовательно, не работает.Как правильно оформить этот запрос, чтобы исключить текущего пользователя?

1 Ответ

0 голосов
/ 11 июня 2018

Этот ответ направлен на решение проблемы , следующей за (поскольку она довольно сложная, я хочу убедиться, что она точно соответствует):

" Набор запросовкоторый содержит Quiz zes, где мы исключаем Quiz zes, у которых ровно один участник в списке users ".Таким образом, эти опросы являются , а не частью набора запросов.

Я бы каждый раз подсчитывал количество перекрытий, а затем исключал бы Quiz zes, где число перекрытий равнов ноль.Что-то вроде:

Quiz.objects.filter(
    <b>Q(players__in=users) | Q(players__isnull=True)</b>
).annotate(
    <b>overlap_size=Count('players')</b>
).exclude(<b>overlap_size=1</b>)

Таким образом, мы всегда вычисляем " overlap ": количество пользователей, которые оба в вашем списке users, и всписок участников.Затем мы исключаем Quiz zes, где это перекрытие точно равно единице, и, следовательно, оцениваем, где точно был один участник, который был в списке users.

На случай, если вам нужны тестыесли перекрытие ровно одно, вам нужно заменить .exclude(..) (в конце) на .filter(..).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...