Middleware einrichten
Middleware sind Komponenten im Request-Response-Zyklus von Django. Sie werden zwischen eingehenden Requests und ausgehenden Responses ausgeführt und ermöglichen es, zentrale Logik an einer Stelle zu kapseln. Typische Anwendungsfälle sind Logging, Authentifizierung oder Sicherheitsprüfungen.
Beispiele für Middlewares
Beispiele sind die Benutzer-Authentifizierung (django.contrib.auth.middleware.AuthenticationMiddleware) oder der Schutz vor CSRF (django.middleware.csrf.CsrfViewMiddleware).
Diese Middlewares werden von Django bereitgestellt und müssen lediglich in den settings.py registriert werden. Eigene Middleware kann ebenfalls problemlos implementiert werden.
Performance Counter Middleware
Wir schreiben eine eigene PerfCountMiddleware, die die Dauer eines Requests misst. Dazu legen wir die Datei event_manager/middleware.py an und fügen folgenden Inhalt ein:
from time import perf_counter
class PerfCountMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = perf_counter()
response = self.get_response(request)
end = perf_counter()
print(f"Die Operation hat {end - start:.2f} Sekunden gedauert")
return response
Intermezzo: Die __call__-Methode
__call__ macht eine Instanz einer Klasse aufrufbar wie eine Funktion. In Django wird diese Methode bei jeder Anfrage durchlaufen.
class Student:
def __init__(self, name):
self.name = name
def __call__(self):
print(f"{self.name} was called")
x = Student("Harry Potter")
x()
Settings
In den Settings aktivieren wir die Middleware. Dazu öffnen wir event_manager/settings/dev.py:
MIDDLEWARE.extend(
[
"debug_toolbar.middleware.DebugToolbarMiddleware",
"event_manager.middleware.PerfCountMiddleware",
]
)
Add Date Middleware
Middleware kann auch den Template-Kontext verändern. Dafür implementieren wir die Methode process_template_response:
from django.utils import timezone
class AddDateMiddleware:
"""Add current timestamp to the global context."""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_template_response(self, request, response):
response.context_data["current_date"] = timezone.now()
return response
Settings
MIDDLEWARE.extend(
[
"debug_toolbar.middleware.DebugToolbarMiddleware",
"event_manager.middleware.PerfCountMiddleware",
"event_manager.middleware.AddDateMiddleware",
]
)
Template
Im Template event_manager/templates/base.html:
{{ current_date }}