Open In App

How to perform OR, AND and NOT in Django QuerySet Filtering

Last Updated : 20 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

We can use the Q objects in django.db.models to create an OR, AND, and NOT filter in a Django query. The Q objects are used to form complex filtering by joining several conditions through logic operators like OR, AND, and NOT. In this article, we will learn to perform AND, OR, and NOT filters while fetching data from databases using Django ORM.

Introduction to Q Objects

By default, query filters in Django use AND logic. If you need to apply OR logic or if you want to do more complex queries involving multiple logical operations like AND, OR, and NOT, Q objects do the trick. Basically, Q objects can be combined with &, |, and ~ operators.

OR Condition

Imagine you have a model Book with fields title, author, and published_date, and you need to select all book where the title contains "Django" or the author contains "GFG".

Python
from django.db.models import Q
from myapp.models import Book

# Get all books where the title contains "Django" OR
# the author name contains "GFG".

books = Book.objects.filter(Q(title__icontains="Django") | Q(author__icontains="GFG"))
print('Books: ' books)
  
for book in books:
	print(book.title, book.author, sep=', ')

Output:

Book: <QuerySet [<Book: Django for Beginners>, <Book: Coding for All>]>
Django for Beginners, GeeksForGeeks
Coding for All, GFG Learning

AND Condition

If you need to use AND logic to combine conditions explicitly, you can do the following using Q objects as well:

Python
# Get all articles where title contains "Django" AND content contains "Python"
book = Book.objects.filter(Q(title__icontains="Django") & Q(content__icontains="GFG"))
print('Books: ', books)
  
for book in books:
	print(book.title, book.author, sep=', ')

Output:

Books:  <QuerySet [<Book: Django Tutorial>]>
Django Tutorial, GFG Learning Center

NOT Condition

You can use the ~ operator (NOT) to exclude certain results.

Python
# Get all books where title does NOT contain "Django"
books = Book.objects.filter(~Q(title__icontains="Django"))
print('Book: ', books)

Output:

Book:  <QuerySet [<Book: A technical Writer >, <Book: Biography of GFG>, <Book: Debug ToolBar Guid>, <Book: Coding for All>]>

Combining Multiple Conditions

You can combine several Q objects to create very specific queries.

Example: Complex Query

Get all articles whose title contains the word "Django" OR whose content contains the word "Python", AND whose date of publication is later than 1st January, 2022.

Python
books = Book.objects.filter(
    (Q(title__icontains="Django") | Q(author__icontains="GFG")) &
    Q(published_date__gt="2024-08-20")
)

for book in books:
	print(book.title, book.author, book.published_date, sep=', ')

Output:

Coding for All, GFG Learning, 2024-08-22

Examples to Implement Django QuerySet Filtering

The following are a few examples of the application of Q objects within Django for handling advanced querying cases:

Example 1: Filtering Users by Several Criteria

Suppose you have a User model with fields like first_name, last_name, email, and is_active. You want to retrieve all users whose first name is "John" or last name is "Doe".

Python
from django.db.models import Q
from django.contrib.auth.models import User

# Find users where first name is "John" OR last name is "Doe"
Get all users with first_name John or last_name Doe.
users = User.objects.filter(Q(first_name='John') | Q(last_name='Doe'))

Example 2: Complex AND and OR Conditions

Suppose that you have a Product model defined with name, category and price fields. You want to select all products either in the "Electronics" category or with a price below $50, and in stock.

Python
from django.db.models import Q
from myapp.models import Product

# Find products where (category is "Electronics" OR price < 50) AND in_stock is True
products = Product.objects.filter
(Q(category='Electronics') | Q(price__lt=50)) & Q(in_stock=True)
)

Example 3: Excluding Records with NOT

Let's say you want to get all the records from a BlogPost model, excluding those for which the title includes "Django".

Python
from django.db.models import Q
from myapp.models import BlogPost

# Get all blog posts except those whose title contains "Django"
posts = BlogPost.objects.filter(~Q(title__icontains='Django'))

Example 4: Complex Filtering on Date Fields

Suppose you have an Event model with fields name, start_date, and end_date. Find all the events that either start after the date or have no end date specified.

Python
from django.db.models import Q
from myapp.models import Event

# Find events where start_date is after '2024-01-01' OR end_date is null
events = Event.objects.filter(Q(start_date__gt='2024-01-01') | Q(end_date__isnull=True))

Conclusion

In Django, the OR filter in a query is accomplished by Q objects. They not only facilitate OR but generally provide a way to construct more complex queries than the default AND logic in the module. You can filter using Q objects with the | operator to find results that have either of the conditions. This will come in very handy in a situation where you would want to fetch records that would satisfy at least one of several conditions. It will enhance the flexibility and power in data fetching through Django's ORM.


Next Article
Article Tags :
Practice Tags :

Similar Reads