Wenn Sie mit Django entwickeln, werden Sie oft auf den Begriff 'Lazy Evaluation' stoßen.
Viele von Ihnen fragen sich möglicherweise, was dieses Konzept genau bedeutet und wie es in Django funktioniert.
In diesem Artikel werden wir untersuchen, was 'Lazy Evaluation' ist und wie es im Django ORM genutzt wird.
1️⃣ Was ist Lazy Evaluation?
"Daten werden erst abgerufen, wenn sie benötigt werden!"
Das QuerySet in Django folgt grundsätzlich der Lazy Evaluation.
Das bedeutet, dass, selbst wenn Sie ein QuerySet erstellen, die Abfrage erst ausgeführt wird, wenn die Daten tatsächlich angefordert werden.
✅ Beispiel: Lazy Evaluation
from myapp.models import Post
# QuerySet erstellen (noch keine Daten aus der DB abrufen)
post_list = Post.objects.filter(status='PB')
print(post_list)
# <QuerySet [ ]># ✅ Abfrage noch nicht in der DB ausgeführt
# 🔥 Die Abfrage wird ausgeführt, wenn die Daten abgerufen werden
for post in post_list:
print(post.title) # 🚀 Abfrage tritt hier auf
- post_list ist ein QuerySet-Objekt, hat aber noch keinen Zugriff auf die DB
- Aber wenn die Daten verwendet werden wird die Abfrage wirklich ausgeführt
✅ Das ist die "Lazy Evaluation"!
2️⃣ Was ist Eager Evaluation?
"Daten sofort abrufen und in eine Liste oder Variable umwandeln!"
Um die Lazy Evaluation zu durchbrechen und das QuerySet sofort auszuführen, kann man Eager Evaluation verwenden.
✅ Beispiel: Eager Evaluation
post_list = list(Post.objects.filter(status='PB')) # ✅ DB-Abfrage wird sofort ausgeführt print(post_list) #
[<Post: Post 1>, <Post: Post 2>] # 🚀 Eine tatsächliche Objektliste wird zurückgegeben, keine QuerySet!
📌 Wenn Eager Evaluation angewendet wird:
- Das QuerySet wird in eine Liste umgewandelt und die Daten werden sofort abgerufen
- Die Funktionen von Django ORM (
.filter()
,.annotate()
) können nicht mehr verwendet werden
3️⃣ Sofortige Bewertung von `.values()` und `.values_list()`
.values()
und .values_list()
behalten grundsätzlich Lazy Evaluation bei, jedoch,
wird sie in Kombination mit list()
sofortig ausgewertet.
✅ Beibehalten der 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-Objekt
🚨 In diesem Zustand ist es immer noch ein QuerySet, daher wird es jedes Mal bewertet, wenn die Daten verwendet werden. 🔥 Eager Evaluation anwenden
post_list = list(Post.objects.filter(status='PB').values("id", "title"))
print(post_list)
# [{'id': 1, 'title': 'First Post'}, {'id': 2, 'title': 'Second Post'}] # 🚀 sofort bewertet (in Liste umgewandelt)
✅ Jetzt hat sich das QuerySet in eine Liste umgewandelt, und die Funktionen von Django ORM (.filter()
, .annotate()
) können nicht mehr verwendet werden. ✅ Aber die Daten wurden im Voraus abgerufen, sodass sie später ohne DB-Zugriff schnell verwendet werden können.
4️⃣ `.count()` und `.exists()` in QuerySet führen eine sofortige Bewertung durch!
Das Django QuerySet folgt grundsätzlich der Lazy Evaluation, aber einige Methoden führen automatisch eine sofortige Bewertung durch.
.count()
(sofortige Abfrage)
post_count = Post.objects.filter(status='PB').count()
# ✅ Abfrage wird sofort ausgeführt (SELECT COUNT(*) FROM post WHERE status='PB';)
.exists()
(sofortige Abfrage)
has_published_posts = Post.objects.filter(status='PB').exists()
# ✅ Abfrage wird sofort ausgeführt (SELECT 1 FROM post WHERE status='PB' LIMIT 1;)
.count()
und .exists()
werden sofort ausgeführt, ohne das QuerySet zu ändern.
5️⃣ Vergleich Lazy Evaluation vs. Eager Evaluation
Lazy Evaluation | Eager Evaluation | |
---|---|---|
Beschreibung | Keine Ausführung der Abfrage, bis sie benötigt wird | Führt sofort Abfragen aus und ruft Daten ab |
Beispiel | Erhält den Status von QuerySet |
list(QuerySet) , .values_list() , .count() |
Vorteil | Verhindert unnötige DB-Abfragen, spart Speicher | Schnelle Nutzung der Daten nach DB-Abfragen |
Nachteil | Abfragen können bei Bedarf ausgeführt werden | Db-Last wird sofort erzeugt, zusätzliche ORM-Operationen sind nicht möglich |
Verwendungsszenario | .filter() , .annotate() , .order_by() |
list() , .count() , .exists() , .values() |
Durch die Anwendung von Eager Evaluation (list(QuerySet)
) werden Daten sofort geladen, und zusätzliche DB-Abfragen können vermieden werden!
Aber da die QuerySet-Funktionen nicht mehr verwendet werden können, sollten Sie sorgfältig entscheiden, wann Sie dies anwenden!
📌 Fazit
✅ Das QuerySet in Django folgt grundsätzlich der Lazy Evaluation.
✅ Mit Eager Evaluation werden Daten sofort aus der DB abgeholt und das QuerySet wird in eine Liste umgewandelt.
✅ Durch das Einwickeln von .values()
und .values_list()
in list()
erfolgt die sofortige Bewertung.
✅ Wenn Sie die Lazy Evaluation beibehalten, können unnötige DB-Abfragen vermieden werden, aber manchmal kann die sofortige Bewertung auch angemessener sein!
Add a New Comment