Wanneer je met Django ontwikkelt, kom je vaak de term 'Lazy Evaluation' tegen.
Maar veel mensen hebben zich misschien afgevraagd wat dit concept precies betekent en hoe het in Django werkt.
In deze blogpost bekijken we wat 'Lazy Evaluation' is en hoe het wordt gebruikt in Django ORM.
1️⃣ Wat is Lazy Evaluation?
"Haal geen gegevens uit de DB totdat het nodig is!"
QuerySets in Django volgen standaard Lazy Evaluation.
Dit betekent dat zelfs als je een QuerySet maakt, de query niet wordt uitgevoerd totdat je daadwerkelijk om gegevens vraagt.
✅ Voorbeeld: Lazy Evaluation
from myapp.models import Post
# Genereer een QuerySet (nog geen gegevens opgehaald uit de DB)
post_list = Post.objects.filter(status='PB')
print(post_list)
# <QuerySet [ ]># ✅ Geen query uitgevoerd op de DB
# 🔥 Zodra gegevens daadwerkelijk worden opgehaald, wordt de DB query uitgevoerd
for post in post_list:
print(post.title) # 🚀 Hier vindt de DB query plaats
- post_list is een QuerySet-object, maar het heeft nog geen toegang tot de DB
- Maar wanneer de gegevens worden gebruikt wordt de query daadwerkelijk uitgevoerd
✅ Dat is precies waar "Lazy Evaluation" voor staat!
2️⃣ Wat is Eager Evaluation?
"Haal gegevens onmiddellijk op en zet ze om naar een lijst of een variabele!"
Als je de Lazy Evaluation wilt doorbreken en de QuerySet onmiddellijk wilt uitvoeren, kun je Eager Evaluation gebruiken.
✅ Voorbeeld: Eager Evaluation
post_list = list(Post.objects.filter(status='PB')) # ✅ DB query wordt onmiddellijk uitgevoerd print(post_list) #
[<Post: Post 1>, <Post: Post 2>] # 🚀 Geen QuerySet maar een echte objectlijst wordt geretourneerd!
📌 Als Eager Evaluation wordt toegepast:
- De QuerySet wordt omgezet in een lijst en haalt onmiddellijk gegevens op
- Functionele mogelijkheden van Django ORM (
.filter()
,.annotate()
) kunnen niet meer worden gebruikt
3️⃣ Eager Evaluation van `.values()` en `.values_list()`
.values()
en .values_list()
behouden standaard Lazy Evaluation, maar als je ze omringt met list()
wordt Eager Evaluation toegepast.
✅ Behouden van 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 deze staat is het nog steeds een QuerySet, dus het wordt elke keer geëvalueerd wanneer je het gebruikt. 🔥 Pas Eager Evaluation toe
post_list = list(Post.objects.filter(status='PB').values("id", "title"))
print(post_list)
# [{'id': 1, 'title': 'First Post'}, {'id': 2, 'title': 'Second Post'}] # 🚀 Eager Evaluation uitgevoerd (omgezet naar lijst)
✅ Nu is het geen QuerySet meer, maar een lijst en kunnen de Django ORM-functies (.filter()
, .annotate()
) niet meer worden gebruikt. ✅ Maar doordat de gegevens vooraf zijn opgehaald, zijn ze later sneller te gebruiken zonder DB-toegang.
4️⃣ In QuerySet worden .count()
en .exists()
onmiddellijk geëvalueerd!
Django QuerySets zijn meestal lazy evaluatie, maar sommige methoden voeren automatisch een directe evaluatie uit.
.count()
(directe query uitvoering)
post_count = Post.objects.filter(status='PB').count()
# ✅ directe query uitvoering (SELECT COUNT(*) FROM post WHERE status='PB';)
.exists()
(directe query uitvoering)
has_published_posts = Post.objects.filter(status='PB').exists()
# ✅ directe query uitvoering (SELECT 1 FROM post WHERE status='PB' LIMIT 1;)
.count()
en .exists()
worden direct uitgevoerd zonder de QuerySet te converteren.
5️⃣ Vergelijking van Lazy Evaluation vs. Eager Evaluation
Lazy Evaluation | Eager Evaluation | |
---|---|---|
Beschrijving | Voert de query niet uit totdat het nodig is | Voert de query uit en haalt gegevens onmiddellijk op |
Voorbeeld | Behoudt QuerySet status |
list(QuerySet) , .values_list() , .count() |
Voordeel | Voorkomt onnodige DB-queries, bespaart geheugen | Toegankelijkheid van gegevens na DB-oproep is snel |
Nadeel | Kan de query uitvoeren als het nodig is | DB-lasten worden onmiddellijk gegenereerd, extra ORM-bewerkingen zijn niet mogelijk |
Gebruik voorbeeld | .filter() , .annotate() , .order_by() |
list() , .count() , .exists() , .values() |
Toepassen van Eager Evaluation (list(QuerySet)
) zorgt ervoor dat gegevens onmiddellijk worden geladen en extra DB-queries worden voorkomen!
Maar doordat de QuerySet-functionaliteit niet meer kan worden gebruikt, moet je zorgvuldig beslissen wanneer je dit toepast!
📌 Conclusie
✅ De QuerySet in Django volgt standaard Lazy Evaluation.
✅ Door Eager Evaluation te gebruiken, haal je gegevens onmiddellijk uit de DB en wordt de QuerySet omgezet in een lijst.
✅ Door .values()
, .values_list()
met list()
te omringen, wordt Eager Evaluation toegepast.
✅ Behoud van Lazy Evaluation kan onnodige DB-queries voorkomen, maar soms is Eager Evaluation geschikter!
댓글이 없습니다.