So richten Sie benutzerdefinierte Middleware in Django ein

79

Ich versuche, Middleware zu erstellen, um optional ein kwarg an jede Ansicht zu übergeben, die eine Bedingung erfüllt.

Das Problem ist, dass ich kein Beispiel für die Einrichtung der Middleware finden kann. Ich habe Klassen gesehen, die die gewünschte Methode überschreiben process_view:

Class CheckConditionMiddleware(object):  
    def process_view(self, request):  

        return None  

Aber wo lege ich diese Klasse hin? Erstelle ich eine Middleware-App, füge diese Klasse ein und verweise darauf settings.middleware?

Atma
quelle
2
Sie können eine meiner Antworten hier folgen: stackoverflow.com/questions/17751163/…
Hieu Nguyen
Das ist zwar eine gute Antwort, aber Sie können auch dem Django-Buch
karthikr
Sie können dies tun: stackoverflow.com/questions/17751163/…
Atma
@karthikr der Link, den Sie gegeben haben, ist defekt: /
fedorqui 'SO hör auf zu schaden'

Antworten:

137

Erstens: Die Pfadstruktur

Wenn Sie es nicht haben, müssen Sie den Middleware- Ordner in Ihrer App folgendermaßen erstellen :

yourproject/yourapp/middleware

Die Ordner-Middleware sollte sich im selben Ordner wie settings.py, urls, templates ... befinden.

Wichtig: Vergessen Sie nicht, die leere Datei __init__.py im Middleware-Ordner zu erstellen, damit Ihre App diesen Ordner erkennt

Zweitens: Erstellen Sie die Middleware

Jetzt sollten wir eine Datei für unsere benutzerdefinierte Middleware erstellen. In diesem Beispiel möchten wir eine Middleware verwenden, die die Benutzer anhand ihrer IP- Adresse filtert. Wir erstellen eine Datei mit dem Namen filter_ip_middleware.py im Middleware- Ordner mit folgendem Code:

class FilterIPMiddleware(object):
    # Check if client IP is allowed
    def process_request(self, request):
        allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # Authorized ip's
        ip = request.META.get('REMOTE_ADDR') # Get client IP
        if ip not in allowed_ips:
            raise Http403 # If user is not allowed raise Error

       # If IP is allowed we don't do anything
       return None

Drittens: Fügen Sie die Middleware in unserer 'settings.py' hinzu.

Wir müssen suchen nach:

  • MIDDLEWARE_CLASSES (Django <1,10)
  • MIDDLEWARE (django> = 1,10)

Innerhalb der settings.py und dort müssen wir unsere Middleware hinzufügen ( an der letzten Position hinzufügen ). Es sollte so sein:

MIDDLEWARE = ( #  Before Django 1.10 the setting name was 'MIDDLEWARE_CLASSES'
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
     # Above are django standard middlewares

     # Now we add here our custom middleware
     'yourapp.middleware.filter_ip_middleware.FilterIPMiddleware'
)

Erledigt ! Jetzt ruft jede Anfrage von jedem Client Ihre benutzerdefinierte Middleware auf und verarbeitet Ihren benutzerdefinierten Code!

AlvaroAV
quelle
Ist der Pfad für die Datei richtig? Sollte es nicht stattdessen Ihr Projekt / Ihre App / Middleware sein?
Tiagovrtr
Ja @tiagovrtr der Pfad sollte sein yourproject/yourapp/middleware. Ich nahm an, dass es ziemlich offensichtlich war, aber ich werde es aktualisieren, wenn das Sie ausräumt
AlvaroAV
9
Überprüfen Sie diese Antwort, wenn Sie TypeError: object() takes no parameters
T. Christiansen
3

Nur zwei Schritte. Es funktioniert bei mir mit django2.1.

1.Erstellen Sie Ihre eigene Middleware-Klasse.

Es gibt eine gute Demo aus dem offiziellen Handbuch.

https://docs.djangoproject.com/de/2.1/ref/request-response/#django.http.HttpRequest.get_host

    from django.utils.deprecation import MiddlewareMixin

    class MultipleProxyMiddleware(MiddlewareMixin):
        FORWARDED_FOR_FIELDS = [
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED_HOST',
            'HTTP_X_FORWARDED_SERVER',
        ]

        def process_request(self, request):
            """
            Rewrites the proxy headers so that only the most
            recent proxy is used.
            """
            for field in self.FORWARDED_FOR_FIELDS:
                if field in request.META:
                    if ',' in request.META[field]:
                        parts = request.META[field].split(',')
                        request.META[field] = parts[-1].strip()

2.Referenzieren Sie Ihre Middleware-Klasse in der MIDDLEWAREListe Ihrer Projektdatei setting.py.

Die Regel für die Middleware-Referenz ist der Pfad zu Ihrer Klasse aus dem Stammverzeichnis Ihres Projekts.

In einem Projekt mit dem Namen mysitelautet der Baum beispielsweise wie folgt.

├── mysite
│   ├── manage.py
│   ├── mysite
│   │   ├── __init__.py
│   │   ├── middleware.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py

Wir fügen einfach unsere Middleware-Klasse MultipleProxyMiddlewarein die middleware.pyDatei ein. Wir erhalten den folgenden Referenznamen.

MIDDLEWARE = [
    'mysite.middleware.MultipleProxyMiddleware',  
     ...
]
W.Perrin
quelle
-3

Dies ist hilfreich, wenn Sie wissen, welche Art von Ausnahme in den Ansichten auftritt. Von oben habe ich meine eigene benutzerdefinierte Klasse wie erstellt

from .models import userDetails

class customMiddleware(object):

    def process_request(self,request):
        result=''
        users = userDetails.objects.all()
        print '-->',users ,'---From middleware calling ---'

        username=request.POST.get("username")
        salary = request.POST.get("salary")
        if salary:
            try:
                result = username+int(salary)
            except:
                print "Can't add"

Es wird ausgeführt, wenn die Ausnahme beim Hinzufügen von Zeichenfolgen und Ganzzahlen auftritt.

Sie können entsprechende Ansichten für die oben genannte Middleware-Klasse schreiben

user6061091
quelle