Middleware
Diese Dokumentation gilt für Djangos Entwicklerversion, die zum Teil erhebliche Unterschiede zur letzten veröffentlichen Version aufweist.
Middleware ist ein Framework, um sich in Djangos Request/Reponse-Verarbeitung einzuhaken. Es ist ein leichtgewichtiges, systemnahes “Plugin”-System, um systemweit die Input- und/oder Output-Daten zu verändern.
Jede Middleware-Komponente ist für die Ausführung von spezifischen Funktionen verantwortlich. Zum Beispiel enthält Django die Middleware-Komponente` XViewMiddleware, die einen "X-View“-HTTP-Header an jeden Response eines HEAD-Request hinzufügt.
Dieses Dokument beschreibt alle Middleware-Komponenten, die in Django enthalten sind, wie man diese verwendet und wie man seine eigene Middleware schreibt.
Middleware aktivieren
Um eine Middleware-Komponente zu aktivieren, musst du sie der MIDDLEWARE_CLASSES-Liste in deinen Django-Einstellungen hinzufügen. In MIDDLEWARE_CLASSES wird jede Middleware-Komponente durch einen String repräsentiert: der vollständige Python-Pfad zum Middleware-Klassen-Namen. Zum Beispiel die Standard-MIDDLEWARE_CLASSES, die beim Aufruf von django-admin.py startproject angelegt wird:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.doc.XViewMiddleware',
)
Django wendet die Middleware-Komponenten in der Reihenfolge, wie sie in MIDDLEWARE_CLASSES gesetzt wurden, an. Außer bei Response- und Exception-Middleware-Komponenten, dort werden sie in umgekehrter Reihenfolge ausgeführt.
Eine Django-Installation benötigt überhaupt keine Middleware — z.B. kann MIDDLEWARE_CLASSES leer sein, falls du möchtest — allerdings wird dringend empfohlen,``CommonMiddleware`` zu verwenden.
Verfügbare Middleware-Komponenten
CacheMiddleware
Vollständiger Pfad zum View: django.middleware.cache.CacheMiddleware
Aktiviert den Cache für die ganze Website. Falls diese aktiviert wurde, wird jede von Django betriebene Seite solange im Cache gespeichert, wie es in der CACHE_MIDDLEWARE_SECONDS-Einstellung definiert ist. Siehe die Cache Dokumentation.
CommonMiddleware
Vollständiger Pfad zum View: django.middleware.common.CommonMiddleware
Stellt Komfort-Funktionalität für Perfektionisten zur Verfügung:
Untersagt den Zugriff von User-Agents über die DISALLOWED_USER_AGENTS-Einstellung. Diese sollte eine Liste von Strings sein.
Führt anhand der Einstellungen APPEND_SLASH und PREPEND_WWW URL-Rewrites durch.
Falls APPEND_SLASH auf True gesetzt ist und die initiale URL nicht mit einem Schrägstrich endet und diese nicht in URLconf gefunden wurde, dann wird eine neue URL gestaltet, indem ein Schrägstrich am Ende angefügt wird. Falls diese neue URL in der URLconf gefunden wird, leitet Django den Request auf diese neue URL um. Andernfalls wird die initiale URL wie gewöhnlich verarbeitet.
Zum Beispiel wird foo.com/bar auf foo.com/bar/ umgeleitet, falls kein gültiges URL-Muster für foo.com/bar, aber für foo.com/bar/ existiert.
Neu in Djangos Entwicklerversion: Das Verhalten von APPEND_SLASH hat sich in der Entwicklerversion ein wenig geändert. Es wird nicht mehr überprüft, ob das Muster in der URLconf trifft.
Falls PREPEND_WWW auf True gesetzt ist, werden URLs ohne führendes www. auf die selbe URL mit führendem “www.” umgeleitet.
Beide Optionen sind dazu gedacht, URLs zu vereinheitlichen. Die Philosophie dahinter ist, dass jede URL an einer, genau einer, Stelle existiert. Technisch gesehen ist die URL foo.com/bar verschieden zu foo.com/bar/ — ein Suchmaschinen-Indizierer würde beide als getrennte URLs behandeln — deswegen ist das Normalisieren von URLs das optimale Verfahren.
Verarbeitet ETags basierend auf der USE_ETAGS-Einstellung. Falls USE_ETAGS` True gesetzt ist, wird Django eine ETag für jeden Request berechnen, indem vom Seiteninhalt ein MD5-Hash erstellt wird. Mit diesem Wert können dann, falls zutreffend, Not Modified-Responses versendet werden.
XViewMiddleware
Vollständiger Pfad zum View: django.middleware.doc.XViewMiddleware
Versendet spezielle X-View-HTTP-Header anhand von HEAD-Requests, die von einer IP-Adresse kommen, die in der INTERNAL_IPS-Einstellung definiert ist. Diese Funktionalität wird im automatischen Dokumentationssystem von Django verwendet.
GZipMiddleware
Vollständiger Pfad zum View: django.middleware.gzip.GZipMiddleware
Komprimiert den Inhalt für Browser, welche die GZIP-Kompression (alle aktuellen Browser) unterstützen.
Es wird empfohlen, dass diese an erster Stelle in der Middleware-Liste gesetzt wird, sodass die Kompression des Response-Inhalts als letztes ausgeführt wird. Es wird der Inhalt nicht komprimiert, falls dieser weniger als 200 Bytes lang ist, der Response-Code nicht 200 ist, es sich um Javascript-Dateien (für IE-Kompatibilität) handelt oder falls der Content-Encoding-Header bei einem Response schon definiert ist.
ConditionalGetMiddleware
Vollständiger Pfad zum View: django.middleware.http.ConditionalGetMiddleware
Behandelt bedingte GET-Operationen. Falls der Response eine ETag- oder Last-Modified-Header und der Request einen If-None-Match oder If-Modified-Since enthält, wird der Response durch HttpNotModified ersetzt.
Setzt auch die Date- und Content-Length-Response-Header.
SetRemoteAddrFromForwardedFor
Vollständiger Pfad zum View: django.middleware.http.SetRemoteAddrFromForwardedFor
Setzt request.META['REMOTE_ADDR'] basierend auf request.META['HTTP_X_FORWARDED_FOR'], falls der letzere gesetzt ist. Das ist hilfreich, falls man sich hinter einem Reverse-Proxy befindet, der REMOTE_ADDR für jeden Request auf 127.0.0.1 setzt.
Wichtiger Hinweis: Diese validiert HTTP_X_FORWARDED_FOR NICHT. Falls du nicht hinter einem Reverse-Proxy sitzst, der automatisch HTTP_X_FORWARED_FOR setzt, verwende diese Middleware nicht. Jeder kann den Wert von HTTP_X_FORWARED_FOR verändern. Und da dieser anhand von HTTP_X_FORWARDED_FOR REMOTE_ADDR setzt, bedeutet dies, dass jeder seine IP-Adresse “fälschen” kann. Verwende diese nur, wenn du dem Wert von HTTP_X_FORWARDED_FOR wirklich trauen kannst.
LocaleMiddleware
Vollständiger Pfad zum View: django.middleware.locale.LocaleMiddleware
Schaltet die Sprachauswahl basierend auf den Daten des Requests an. Sie passt den Inhalt für jeden User an. Siehe die Dokumentation zur Internationalisierung.
SessionMiddleware
Vollständiger Pfad zum View: django.contrib.sessions.middleware.SessionMiddleware
Aktiviert die Session-Unterstützung. Siehe Session Dokumentation.
AuthenticationMiddleware
Vollständiger Pfad zum View: django.contrib.auth.middleware.AuthenticationMiddleware
Fügt das User-Attribut, das den aktuell angemeldeten User repräsentiert, jedem eingehenden HttpRequest-Objekt hinzu. Siehe Authentifizierung bei Web-Requests.
CsrfMiddleware
Vollständiger Pfad zum View: django.contrib.csrf.middleware.CsrfMiddleware
Neu in Djangos Entwicklerversion
Fügt Schutz vor Cross Site Request Forgeries (Request-Fälschung) hinzu, indem versteckte Formularfelder zu POST-Formulare hinzugefügt werden, um die Requests auf korrekte Werte zu überprüfen. Siehe die Dokumentation über den Schutz vor “Cross Site Request Forgery”-Angriffen.
TransactionMiddleware
Vollständiger Pfad zum View: django.middleware.transaction.TransactionMiddleware
Bindet Commit und Rollback an die Request/Respone-Phase. Falls eine View-Funktion erfolgreich durchgelaufen ist, wird ein Commit ausgeführt. Falls diese mit einer Exception fehlschlägt, wird ein Rollback durchgeführt.
Die Position dieser Middleware in der Middleware-Liste ist wichtig: Middleware-Module, die außerhalb dieser laufen (vorher in der Liste), werden mit “Commit beim Speichern” ausgeführt - Djangos Standard-Verhalten. Middleware-Module, die innerhalb dieser Middleware (die in der Liste danach kommen) ausgeführt werden, nutzen die gleiche Transaktions-Kontrolle, wie die View-Funktionen.
Siehe die Transaktion-Verwaltungs-Dokumentation.
Schreib deine eigene Middleware
Es ist einfach, eine eigene Middleware zu schreiben. Jede Middleware-Komponente ist eine einzelne Python-Klasse, die eine oder mehrere der folgenden Methoden definiert:
process_request
Interface: process_request(self, request)
request ist ein HttpRequest-Objekt. Diese Methode wird bei jedem Request, bevor Django entscheidet, welche View ausgeführt wird, aufgerufen.
process_request() sollte entweder None oder ein HttpResponse-Objekt zurückliefern. Falls es None zurückgibt, wird Django die Verarbeitung des Requests fortsetzen, jede andere Middleware und dann die zugehörige View ausführen. Falls es ein HttpResponse-Objekt zurückgibt, wird sich Django nicht weiter bemühen IRGENDEINEN anderen Request, andere View- oder Exeception-Middleware oder die zugehörige View aufzurufen; es wird HttpResponse zurückgeben. Response-Middleware wird stets bei jedem Response aufgerufen.
process_view
Interface: process_view(self, request, view_func, view_args, view_kwargs)
request ist ein HttpRequest-Objekt. view_func ist die Python-Funktion, die Django im Begriff ist, zu verwenden. (Es ist das aktuelle Funktionsobjekt, nicht der Name der Funktion als String.) view_args ist eine Liste von positionsbezogenen Argumenten, die an die View weitergegeben werden, view_kwargs ist ein Dictionary an Schlüsselwort-Argumenten, die an die View übergeben werden. Weder view_args noch view_kwargs beinhalten das erste View-Argument (request).
process_view() wird, kurz bevor Django die View ausführt, aufgerufen. Sie sollte entweder None oder ein HttpResponse-Objekt zurückgeben. Falls sie None zurückliefert, wird Django die Verarbeitung des Requests fortsetzen, jede andere process_view()-Middleware und dann die zugehörige View ausführen. Falls sie ein HttpResponse-Objekt zurückgegeben wird, wird sich Django nicht weiter bemühen IRGENDEINEN anderen Request, andere View- oder Exception-Middleware oder die zugehörige View aufzurufen; es wird diesen HttpResponse zurückgeben. Response-Middleware wird stets bei jedem Response aufgerufen.
process_response
Interface: process_response(self, request, response)
request ist ein HttpRequest-Objekt. response ist das HttpResponse-Objekt, das von einer Django-View zurückgegeben wird.
process_response() muss ein HttpResponse-Objekt zurückgeben. Es kann den übergebenen response verändern, oder es kann einen erstellen und diesen brandneuen HttpResponse zurückgeben.
process_exception
Interface: process_exception(self, request, exception)
request ist ein HttpRequest-Objekt. exception ist ein Exception-Objekt, das von der View-Funktion geworfen wurde.
Django ruft process_exception() auf, falls eine View eine Exception wirft. process_exception() muss entweder None oder ein HttpResponse-Objekt zurückgeben. Falls sie ein HttpResponse-Objekt zurückgibt, wird der Response an den Browser zurückgeliefert. Andernfalls kommt die Standard-Exception-Behandlung ins Spiel.
Richtlinien
- Middleware-Klassen müssen keine Sub-Klasse von irgendwas sein.
- Die Middleware-Klasse kann irgendwo in deinem Python-Pfad liegen. Das einzige, worum sich Django schert, ist, dass die MIDDLEWARE_CLASSES-Einstellung den Pfad zu diesem enthält.
- Tu dir keinen Zwang an und schau dir für Beispiele die verfügbaren Middleware-Komponenten an. Die Django-Core-Middleware-Klassen befinden sich in django/middleware/ der Django-Distribution. Die Session-Middleware befindet sich in django/contrib/sessions.
- Falls du eine Middleware-Komponente schreibst, von der du denkst, dass diese für andere nützlich ist, steuere sie der Gemeinschaft bei! Lass uns das wissen und wir überlegen uns dann, ob sie Django hinzugefügt wird.