Django Advanced queries with Q objects


Given the model:

class MyModel(models.Model):
    name = models.CharField(max_length=10)
    model_num = models.IntegerField()
    flag = models.NullBooleanField(default=False)

We can use Q objects to create AND , OR conditions in your lookup query. For example, say we want all objects that have flag=True OR model_num>15.

from django.db.models import Q
MyModel.objects.filter(Q(flag=True) | Q(model_num__gt=15))

The above translates to WHERE flag=True OR model_num > 15 similarly for an AND you would do.

MyModel.objects.filter(Q(flag=True) & Q(model_num__gt=15))

Q objects also allow us to make NOT queries with the use of ~. Let's say we wanted to get all objects that have flag=False AND model_num!=15, we would do:

MyModel.objects.filter(Q(flag=True) & ~Q(model_num=15)) 

If using Q objects and "normal" parameters in filter(), then the Q objects must come first. The following query searches for models with (flag set to True or a model number greater than 15) and a name that starts with "H".

from django.db.models import Q
MyModel.objects.filter(Q(flag=True) | Q(model_num__gt=15), name__startswith="H")

Note: Q objects can be used with any lookup function that takes keyword arguments such as filter, exclude, get. Make sure that when you use with get that you will only return one object or the MultipleObjectsReturned exception will be raised.