When developing with Django, you often encounter the term 'Lazy Evaluation'.
However, many of you might wonder what exactly this concept is and how it works in Django.
In this post, we will explore what 'Lazy Evaluation' means and how it is utilized in Django ORM.
1️⃣ What is Lazy Evaluation?
"Do not fetch data from the DB until necessary!"
Django's QuerySet follows Lazy Evaluation by default.
In other words, even if you create a QuerySet, the query is not executed until you actually request the data.
✅ Example: Lazy Evaluation
from myapp.models import Post
# Create a QuerySet (no data fetched from DB yet)
post_list = Post.objects.filter(status='PB')
print(post_list)
# <QuerySet [ ]># ✅ No query executed on DB yet
# 🔥 The DB query is executed when data is actually accessed
for post in post_list:
print(post.title) # 🚀 DB query occurs here
- post_list is a QuerySet object, but it does not access the DB yet
- However, when data is used, the query is executed
✅ This is what "Lazy Evaluation" is!
2️⃣ What is Eager Evaluation?
"Fetch data immediately and convert it into a list or variable!"
To break the paradigm of Lazy Evaluation and execute the QuerySet immediately, you can use Eager Evaluation.
✅ Example: Eager Evaluation
post_list = list(Post.objects.filter(status='PB')) # ✅ Executes DB query immediately print(post_list) #
[<Post: Post 1>, <Post: Post 2>] # 🚀 Returns an actual object list instead of a QuerySet!
📌 Applying Eager Evaluation:
- QuerySet is converted into a list and fetches data immediately
- Can no longer use Django ORM functionality (
.filter()
,.annotate()
)
3️⃣ Immediate Evaluation with `.values()` and `.values_list()`
.values()
and .values_list()
also maintain Lazy Evaluation by default,
but wrapping them in list()
applies immediate evaluation.
✅ Maintaining Lazy Evaluation
post_list = Post.objects.filter(status='PB').values("id", "title")
print(post_list)
# <QuerySet [{'id': 1, 'title': 'First Post'}, {'id': 2, 'title': 'Second Post'}]> # QuerySet object
🚨 In this state, it is still a QuerySet, so it is evaluated every time data is used. 🔥 Apply Immediate Evaluation
post_list = list(Post.objects.filter(status='PB').values("id", "title"))
print(post_list)
# [{'id': 1, 'title': 'First Post'}, {'id': 2, 'title': 'Second Post'}] # 🚀 Evaluated immediately (converted to list)
✅ Now it has become a list instead of a QuerySet, and the Django ORM functionality (.filter()
, .annotate()
) cannot be used. ✅ But since the data has been fetched in advance, it can be quickly utilized without further DB access.
4️⃣ The `.count()` and `.exists()` methods on QuerySet evaluate immediately!
Django QuerySet is usually lazy evaluated, but certain methods automatically execute immediate evaluations.
.count()
(immediate query execution)
post_count = Post.objects.filter(status='PB').count()
# ✅ Executes immediate query (SELECT COUNT(*) FROM post WHERE status='PB';)
.exists()
(immediate query execution)
has_published_posts = Post.objects.filter(status='PB').exists()
# ✅ Executes immediate query (SELECT 1 FROM post WHERE status='PB' LIMIT 1;)
.count()
and .exists()
execute immediately without converting the QuerySet.
5️⃣ Summary Comparison: Lazy Evaluation vs. Eager Evaluation
Lazy Evaluation | Eager Evaluation | |
---|---|---|
Description | Does not execute query until necessary | Executes query immediately and fetches data |
Example | Maintains QuerySet state |
list(QuerySet) , .values_list() , .count() |
Advantage | Prevents unnecessary DB queries, saves memory | Quickly utilize data after DB query |
Disadvantage | Queries might execute every time when needed | Immediate load on DB, no additional ORM operations allowed |
Usage Examples | .filter() , .annotate() , .order_by() |
list() , .count() , .exists() , .values() |
Applying Eager Evaluation (list(QuerySet)
) allows data to be loaded immediately and prevents additional DB queries!
However, since the QuerySet functionalities can no longer be used, careful consideration should be given to when to apply it!
📌 Conclusion
✅ Django's QuerySet follows Lazy Evaluation by default.
✅ Using Eager Evaluation, you can immediately fetch data from the DB and convert the QuerySet into a list.
✅ Wrapping .values()
and .values_list()
with list()
applies immediate evaluation.
✅ Maintaining Lazy Evaluation can prevent unnecessary DB queries, but sometimes immediate evaluation might be more appropriate!
Add a New Comment