Querying with Django Q Objects

MicroPyramid
2 min readMar 2, 2022

Django Q objects:

Q object encapsulates a SQL expression in a Python object that can be used in database-related operations. Using Q objects we can make complex queries with less and simple code.

For example, this Q object filters whether the question starts with ‘what’:

from django.db.models import Q
Q(question__startswith='What')

Q objects are helpful for complex queries because they can be combined using logical operators and(&), or(|), negation(~)

For example, this statement returns if the question starts with ‘who’ or with ‘what’.

Q(question__startswith='Who') | Q(question__startswith='What')

Note:>If the operator is not included then by default ‘AND’ operator is used

The following code is the source of the Q class:

class Q(tree.Node):
AND = 'AND'
OR = 'OR'
default = AND
def __init__(self, *args, **kwargs):
super(Q, self).__init__(children=list(args) + list(six.iteritems(kwargs)))
def _combine(self, other, conn):
if not isinstance(other, Q):
raise TypeError(other)
obj = type(self)()
obj.connector = conn
obj.add(self, conn)
obj.add(other, conn)
return obj
def __or__(self, other):
return self._combine(other, self.OR)
def __and__(self, other):
return self._combine(other, self.AND)
def __invert__(self):
obj = type(self)()
obj.add(self, self.AND)
obj.negate()
return obj

As you can interpret from the above code, we have three operators ‘or’, ‘and’ and invert(negation) and the default operator is AND.

Dynamic querying with Q objects:

This is an interesting feature as we can use the operator module to create dynamic queries.

import operator
from django.db.models import Q
from your_app.models import your_model_object
q_list = [Q(question__startswith='Who'), Q(question__startswith='What')]
your_model_object.objects.filter(reduce(operator.or_, q_list))

We are performing the or operation using operator.or_

To use and operations simply execute:

your_model_object.objects.filter(reduce(operator.and_, q_list))

Q objects not only simplify complex queries, but are also very handy for dynamic filtering.

To know more about our Django CRM(Customer Relationship Management) Open Source Package. Check Code

--

--

MicroPyramid

Python, Django, Android and IOS, reactjs, react-native, AWS, Salesforce consulting & development company