Cómo configurar middleware personalizado en Django

80

Estoy intentando crear middleware para pasar opcionalmente un kwarg a cada vista que cumpla con una condición.

El problema es que no puedo encontrar un ejemplo de cómo configurar el middleware. He visto clases que anulan el método que quiero process_view:

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

        return None  

¿Pero dónde pongo esta clase? ¿Creo una aplicación de middleware y pongo esta clase dentro de ella y luego hago referencia a ella settings.middleware?

Atma
fuente
2
Puede seguir una de mis respuestas aquí: stackoverflow.com/questions/17751163/…
Hieu Nguyen
Si bien esa es una gran respuesta, también puede seguir el libro de django
karthikr
@karthikr el enlace que diste está roto: /
fedorqui 'Así que deja de dañar'

Respuestas:

139

Primero: la estructura del camino

Si no lo tiene, debe crear la carpeta de middleware dentro de su aplicación siguiendo la estructura:

yourproject/yourapp/middleware

El middleware de la carpeta debe colocarse en la misma carpeta que settings.py, urls, templates ...

Importante: no olvide crear el archivo vacío __init__.py dentro de la carpeta de middleware para que su aplicación reconozca esta carpeta

Segundo: crea el middleware

Ahora deberíamos crear un archivo para nuestro middleware personalizado, en este ejemplo supongamos que queremos un middleware que filtre a los usuarios según su IP, creamos un archivo llamado filter_ip_middleware.py dentro de la carpeta del middleware con este código:

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

Tercero: agregue el middleware en nuestro 'settings.py'

Necesitamos buscar:

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

Dentro de settings.py y allí necesitamos agregar nuestro middleware (Agréguelo en la última posición ). Debería ser como:

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'
)

Hecho ! ¡Ahora cada solicitud de cada cliente llamará a su middleware personalizado y procesará su código personalizado!

AlvaroAV
fuente
¿Es correcta la ruta del archivo? ¿No debería ser su proyecto / su aplicación / middleware en su lugar?
tiagovrtr
Sí @tiagovrtr, la ruta debería ser yourproject/yourapp/middleware. Supuse que era bastante obvio, pero lo actualizaré si eso te aclara
AlvaroAV
10
Compruebe esta respuesta si se encuentra con:TypeError: object() takes no parameters
T. Christiansen
3

Solo dos pasos. Me funciona con django2.1.

1. Cree su propia clase de Middleware.

Hay una buena demostración del manual oficial.

https://docs.djangoproject.com/en/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. Haga referencia a su clase de Middleware en la MIDDLEWARElista de su setting.pyarchivo de proyecto .

La regla para la referencia de Middleware es la ruta a su clase desde el directorio raíz de su proyecto.

Por ejemplo, en un proyecto denominado mysite, el árbol es el siguiente.

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

Simplemente agregamos nuestra clase Middleware MultipleProxyMiddlewareen el middleware.pyarchivo. Obtenemos el siguiente nombre de referencia.

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

Será útil en el caso de Cuando sepa qué tipo de excepción ocurre en las vistas. De lo anterior, he creado mi propia clase personalizada como

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"

Se ejecutará cuando ocurra la excepción en el caso de la suma de cadenas y enteros.

Puede escribir vistas correspondientes para la clase de middleware anterior

user6061091
fuente