Heute klären wir das spannende Thema „Verursacht Django's request.session.get() eine Leistungsverschlechterung?“ 🎯

Während der Entwicklung mit Django ruft man häufig request.session.get('key_name') mehrmals auf, oder? Plötzlich kam mir dieser Gedanke.

"Da die Sitzung schließlich in der DB gespeichert wird, wird bei jedem Aufruf von request.session.get() eine DB-Abfrage ausgelöst?"

"Oder hat Django etwas clever verarbeitet, sodass keine zusätzlichen Abfragen erzeugt werden?"

Um diese Neugier zu stillen, habe ich bis tief in den Quellcode von Djangos SessionMiddleware geschaut und es durch Experimente überprüft. 🚀

1️⃣ Wie wird request.session in Django erstellt?

Schauen wir uns an, wann Django die Sitzung beim Erstellen des Anfrageobjekts lädt.

Django session management process

In der Regel holen wir die Sitzungsdaten in einer View-Funktion so:

session_username = request.session.get('username')

Wenn Django jedoch bei jedem Gebrauch von request.session.get('username') eine DB-Abfrage ausführt, könnte dies die Leistung erheblich beeinträchtigen, oder?

🔍 Lass uns einen Blick ins Innere von Django werfen!

Tatsächlich lädt Django durch ein Middleware namens SessionMiddleware die Sitzungsdaten bereits beim Eintreffen der Anfrage. Dabei wird die DB-Abfrage nur einmal ausgelöst, und danach beleibt die Sitzungsdaten im Anfrageobjekt.

Wenn wir den Code von Djangos SessionMiddleware anschauen, sehen wir folgende Verarbeitung:

class SessionMiddleware(MiddlewareMixin):
    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

📌 Wichtiger Punkt!

  • ✅ Der Sitzungsschlüssel (session_key) wird aus request.COOKIES geholt.
  • ✅ Durch den Aufruf von self.SessionStore(session_key) werden die Sitzungsdaten einmal aus der DB geladen und in request.session gespeichert.
  • ✅ Das bedeutet, dass auch beim mehrmaligen Aufruf von request.session.get() keine zusätzlichen DB-Abfragen erfolgen! 🎯

2️⃣ Löst request.session.get() eine DB-Abfrage aus?

Jetzt kommen wir zur Kernfrage zurück.

"Wenn man in einer View request.session.get('username') aufruft, geschieht dann eine DB-Abfrage?"

🚀 Um es vorweg zu sagen, es erfolgt keine zusätzliche DB-Abfrage, wenn request.session.get() aufgerufen wird.

Der Grund ist einfach.
✔ Django lädt die Sitzungsdaten einmal bei der Anfrage und speichert sie in request.session.
✔ Der darauf folgende Aufruf von request.session.get() ist das Abrufen bereits im Speicher geladenen Daten, sodass keine zusätzlichen DB-Abfragen erforderlich sind.

Die momentane DB-Abfrage findet also nur beim ersten Anfrage statt. Die bei diesem Vorgang ausgeführte SQL-Abfrage lautet:

SELECT session_data FROM django_session WHERE session_key = 'xyz123' LIMIT 1;

👉 Das bedeutet, ✅ auch beim mehrmaligen Aufruf von request.session.get() wird von Django keine zusätzliche DB-Abfrage ausgeführt!
👉 ✅ Das Abrufen von Daten aus der DB wird nur einmal beim ersten Auftreten der Anfrage ausgeführt!

3️⃣ Entsteht bei der Verwendung von Sitzungsdaten im Template ebenfalls eine Abfrage?

"Tritt auch eine zusätzliche DB-Abfrage auf, wenn Sitzungsdaten, die in der View abgerufen und dann an das Template übergeben werden, im Template verwendet werden?"

Angenommen, wir übergeben die Sitzungsdaten in der View so:

def my_view(request):
    session_username = request.session.get('username')  # DB-Abfrage? ❌
    return render(request, 'my_template.html', {'session_username': session_username})

Und im Template verwenden wir es so:

<p>Eingeloggt als: {{ session_username }}</p>

In diesem Fall erfolgt auch keine zusätzliche DB-Abfrage!

session_username ist der bereits von request.session abgerufene Wert, daher sind beim Übergeben an das Template keine zusätzlichen DB-Abfragen erforderlich.

✔ Django verwaltet request.session wie einen Speicher-Cache, sodass es auch im Template sicher verwendet werden kann.


4️⃣ Werden Änderungen an Sitzungsdaten in der DB gespeichert?

"Was passiert, wenn ich Daten wie request.session['username'] = 'new_value' ändere?"

🚀 In diesem Fall werden die Änderungen in der DB gespeichert, was zu einer zusätzlichen DB-Abfrage führt!

Wenn man die Sitzungsdaten wie folgt ändert:

request.session['username'] = 'new_value'

Speichert Django beim Senden der Antwort die geänderten Sitzungsdaten in der DB. Die SQL-Abfrage, die dabei ausgeführt wird, lautet:

UPDATE django_session SET session_data = 'new_value' WHERE session_key = 'xyz123';

Das Lesen von Sitzungen verursacht keine DB-Abfragen, aber beim Ändern der Sitzung führt Django eine DB-Abfrage aus, um dies zu speichern.


5️⃣ Unterschiede je nach Speicherbackend für Sitzungen

Django erlaubt die Änderung des Speichersystems (Backend) für Sitzungen. Je nach Backend gibt es Unterschiede bezüglich der Abfrageauslösung.

Sitzungs-Backend Beschreibung DB-Abfrage erfolgt?
django.contrib.sessions.backends.db Standardmäßige DB-basierte Sitzung ✅ Einmal bei der Anfrage
django.contrib.sessions.backends.cache Cache-basierte Sitzung (Redis, Memcached) ❌ Keine DB-Abfragen
django.contrib.sessions.backends.cached_db Cache + DB-Sitzung (DB-Abfrage, falls im Cache nicht vorhanden) 🚀 Tritt auf, falls nicht im Cache
django.contrib.sessions.backends.signed_cookies Cookie-basierte Sitzung ❌ Keine DB-Abfragen

🚀 Das bedeutet, dass man, indem man cache oder signed_cookies als Backend verwendet, Sitzungen ohne DB-Abfragen abrufen kann. ✔ Bei starker Leistungseffizienz kann es auch nützlich sein, CACHED_DB_SESSION in Betracht zu ziehen.


🎯 Fazit

  • ✅ Django lädt die Sitzungsdaten zu Beginn der Anfrage durch SessionMiddleware und speichert sie im request.session Objekt.
  • ✅ Daher führt der Aufruf von request.session.get('username') in der View keine zusätzlichen DB-Abfragen aus.
  • Auch bei der Verwendung von Sitzungsdaten im Template kommen keine zusätzlichen DB-Abfragen zustande.
  • ✅ Allerdings speichert Django, wenn die Sitzungswerte geändert werden, die geänderten Daten bei der Antwort in der DB.
  • ✅ Abhängig von Djangos Sitzungsbackend-Einstellungen kann es Unterschiede in der Abfrageauslösung geben, sodass man durch die Verwendung von Cache-basierten (cache oder cached_db) Ansätzen die DB-Belastung reduzieren kann.

🔥 Vorschau auf die nächste Folge: Wann verschwindet das request-Objekt?

Wann also verschwindet das request-Objekt?

  • Belegt es weiterhin Speicher, selbst nachdem die Anfrage abgeschlossen ist?

  • Wird es automatisch vom System aufgeräumt, oder müssen wir selbst aufräumen?

🚀 In der nächsten Folge werden wir die Lebensdauer des request-Objekts und das Speicherverwaltung bei Django untersuchen! Seid gespannt! 😃