How to perform OR condition in django queryset?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
In Django, chaining multiple keyword arguments inside one filter() call produces an AND, not an OR. To express OR logic, the normal tool is Q objects, which let you combine conditions explicitly and build more complex query expressions without dropping into raw SQL.
Use Q Objects for OR
Import Q from django.db.models and combine expressions with the bitwise | operator.
That query returns books that match either side of the condition. Without Q, two keyword filters would be combined with AND instead.
Group Conditions Deliberately
Q objects become especially useful when the query contains both OR and AND. Parentheses matter because they control how the logic is grouped.
This means:
- author is
Author1orAuthor2 - and the book must also be published
If you remove the parentheses, the logic changes. Treat Q expressions like boolean algebra, because that is effectively what they are.
Build Dynamic OR Queries
One reason Q objects are so useful is that they make runtime query construction straightforward. Suppose the user can search across title, subtitle, and author with one input string.
This is cleaner than writing raw SQL and still gives Django a normal queryset it can further filter, order, paginate, or combine.
That composability is a major reason to prefer ORM expressions here. The result stays inside Django's query system instead of becoming a special-case string query you have to maintain separately.
Combine Q Objects Incrementally
You do not need to write the whole expression in one line. Incremental construction is often clearer when the conditions are optional.
Starting with Q() lets you build up the final expression step by step while preserving readable logic.
Watch for Duplicate Rows After Joins
When the queryset crosses relations, OR conditions can produce duplicate rows because the SQL joins may match multiple related records. In those cases, distinct() is often the missing piece.
If you forget distinct(), the query may look correct but return the same Book more than once.
Common Pitfalls
The most common mistake is expecting multiple keyword filters to mean OR. In Django, filter(author="A", title="B") always means both conditions must be true.
Another issue is forgetting parentheses when mixing | and &. The expression may still run, but it may encode different logic than you intended.
Developers also sometimes use raw SQL too early. Q objects cover a large amount of normal boolean query logic and keep the result as a queryset that still works with the rest of the ORM.
Finally, be careful when traversing many-to-many or reverse foreign-key relations. OR logic across joins can create duplicates, and distinct() may be necessary to get the semantic result you expected.
Summary
- Use
Qobjects to expressORconditions in Django querysets. - Combine them with
|forORand&forAND. - Add parentheses to make mixed boolean logic explicit.
- Build
Qexpressions incrementally when the query depends on runtime input. - Use
distinct()when relation joins cause duplicate rows.
Related reading
- How to persist a property of type ListString in JPA?
- How to persist data in a dockerized postgres database using volumes
- How to persist data using a postgres database, Docker, and Kubernetes?
- How to pg_dump an RDS Postgres database?
- How to pick just one item from a generator?
- How to pickle Keras model?
- How to pick a Kafka transaction.id
- How to place SQLite database outside of NFS Persistent Volume

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.