Querying with Django Q objects

Reading Time : ~ .

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 wiht 'what':

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

Q objects are helpfull 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 source of 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 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, they are very handy for dynamic filtering.

 

 

 

 

 

 

 

 

 

 

 

 

 

    By Posted On
SENIOR DEVELOPER at MICROPYRAMID

Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Dynamically Adding Google Maps with Marker In Django Nikhila Mergu

Google Maps allows you to display maps on your web site, we can also customize maps, and the information on maps.
The Google Maps API ...

Continue Reading...
Working with Django Plugins Vinisha Naladala

This blog describes about how to work with django-plugins. Django Plugin is a Simple Plugin Framework for Django. By using django-plugins, you can make your ...

Continue Reading...
Sending emails using sendgrid on heroku for a Django App Vinisha Naladala

Integrate Sendgrid API to your Heroku app to deliver simplified emails like any notification emails, user signups etc.

Continue Reading...

Subscribe To our news letter

Subscribe to our news letter to receive latest blog posts into your inbox. Please fill your email address in the below form.
*We don't provide your email contact details to any third parties