Сложный запрос ORM в 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)
    full_name = models.CharField(max_length=255, blank=True, null=True)
    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)
    winners = models.ManyToManyField(User, related_name='quizzes_won')
    losers = models.ManyToManyField(User, related_name='quizzes_lost')

Я хочу запросить все викторины, которые пользователь не играл, таким образом, победители и проигравшиене содержит идентификатор пользователя.Как мне это сделать.Извините, я новичок в Джанго.

Ответы [ 2 ]

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

Мы можем использовать .exclude(..) здесь и в качестве критерия, что User находится в отношении winners или losers.Итак:

from django.db.models import <b>Q</b>

Quiz.objects<b>.exclude(Q(winners=user) | Q(losers=user))</b>

Здесь Q [doc] - это объект, который инкапсулирует определенный предикат.Используя оператор «или» |, мы указываем как условие, что winners содержит user, или loser содержит user.Таким образом, мы исключаем Quiz zes, которые удовлетворяют как минимум одному (или обоим) из этих критериев.

Это приводит к серверной части MySQL в запросе, подобном:

SELECT `quiz`.*
FROM `quiz`
WHERE NOT (
    (  `quiz`.`id` IN (SELECT U1.`quiz_id` AS Col1
                       FROM `quiz_winners` U1
                       WHERE U1.`user_id` = 123)
    OR `quiz`.`id` IN (SELECT U1.`quiz_id` AS Col1
                       FROM `quiz_losers` U1
                       WHERE U1.`user_id` = 123)
    )
)

(где 123 на самом деле id из user)

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

Вы можете использовать exclude:

Quiz.objects.exclude(winners=my_user).exclude(losers=my_user)
...