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! 

 

Django QuerySet Lazy vs Eager Evaluation