Skip to content

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")
Or even in more complex conditions:

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)