The Q Object¶
The get
, filter
, and exclude
methods of QuerySet accept Q objects as arguments.
The Q objects provide the ability to build complex, nested, grouped conditions for these methods.
from amsdal_utils.query.utils import Q
# equal to (age < 30 & age > 50)
Q(age__lt=30, age__gt=50)
# equal to (gender == "male" and age > 60) or (gender == "female" and age > 50)
Q(gender="male", age__gt=60) | Q(gender="female", age__gt=50)
Or even more complex:
from amsdal_utils.query.utils import Q
# equal to (gender == "male" and (age < 18 or age > 21))
Q(gender="male") & Q(Q(age__lt=18) | Q(age__gt=21))
So you can build complex dynamic conditions and pass them to QuerySet methods:
from amsdal_utils.query.utils import Q
from models.user.person import Person
conditions = Q(age__lt=18) | Q(gender="female")
person_qs = Person.objects.filter(
conditions,
city="London",
).exclude(Q(name="John") | Q(name="Bob"))
The Q object also can be converted to a negative condition just by adding ~
before the Q:
from amsdal_utils.query.utils import Q
# equal to (age < 18) or gender != "female")
conditions = Q(age__lt=18) | ~Q(gender="female")
from amsdal_utils.query.utils import Q
from models.user.person import Person
original_conditions = Q(gender="male") & Q(Q(age__lt=18) | Q(age__gt=21))
negative_conditions = ~Q(original_conditions)
qs = Person.objects.filter(negative_conditions)
# that is equal to
qs = Person.objects.exclude(original_conditions)