简体   繁体   中英

Complex ORM query in django

This is my User

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)

And this is my Quiz model,

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')

I want to query all quizzes that an user has not played, thus winners and losers does not contain user id. How do I do this. Sorry I'm new to django.

您可以使用exclude

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

We can use .exclude(..) here and as criterion that the User is in the winners or losers relation. So:

from django.db.models import 

Quiz.objects

Here Q [doc] is an object that encapsulated a certain predicate. By using the "or" operator | we thus specify as condition that winners contains user , or loser contains user . We exclude thus Quiz zes that satisfy at least one (or both) of these criteria.

This results with a MySQL backend in a query like:

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)
    )
)

(where 123 is in fact the id of the user )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM