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 }}

Mehr Infos zur Middleware: