Django – Q() objects
Django Q() object helps to define SQL condition on the database and can be combined with the &(AND) and |(or) operator. Q() helps in the flexibility of defining and reusing the conditions.
- Using Q() objects to make an AND conditions.
- Using Q() objects to make an OR conditions.
- Using Q() objects to make reusable conditions.
Using Q() objects to make an AND conditions We can use Q() objects to combine multiple filter conditions into one condition as filter conditions always perform AND operations.
from django.db.models import Q # Without Q() object document_obj = Document.objects.filter(created_by=1282).filter(doc_type='purchase_order').filter(edit=0).filter(cancelled=0) #With Q() object q_filter_document = Q(created_by=1282) & Q(doc_type='purchase_order') & Q(cancelled=0) &(edit=0) # can also be written as q_filter_document_another_way = Q(created_by=1282, doc_type='purchase_order', cancelled=0, edit=0) document_obj = Document.objects.filter(q_filter_document)
Using Q() objects to make an OR conditions
from django.db.models import Q #With Q() object q_filter_document = Q(created_by=1282) | Q(created_by=1282) document_obj = Document.objects.filter(q_filter_document)
Q() to make reusable filter condition The best use of Q() objects is reusability, we define the Q() once and can use them to combine with different Q() objects with help of &, |, and ~ operators.
Let's consider a use case, in which the user can generate a report based on certain filters. User can filter report based on these values documenttype, isdraft, createdby, documentstatus
def get_document_object(document_type, is_draft, created_by, document_status): base_query = Q(active=1, cancelled=0, document_tye=document_type, is_draft=is_draft) # based on condition we can different Q() objects to filter the tables if document_status = 'in_progress': base_query = base_query & Q(document_status=document_status, completed=0) else if document_status = 'completed': base_query = base_query & Q(document_status=document_status, completed=1) return Documents.objects.filter(base_query)
In Q() objects we can use the same conditional operator which we use in filter objects like in operator, startswith, endswith, etc.
Conclusion Q() objects contribute to clean code and reusability. It helps to define the condition with &, |, and ~ relation operator to simplify the complex queries.