Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Middlewares

23/37
Recursos

Un middleware en Django es una serie de hooks y una API de bajo nivel que nos permiten modificar el objeto request antes de que llegue a la vista y response antes de que salga de la vista.

Django dispone de los siguientes middlewares por defecto:

  • SecurityMiddleware
  • SessionMiddleware
  • CommonMiddleware
  • CsrfViewMiddleware
  • AuthenticationMiddleware
  • MessageMiddleware
  • XFrameOptionsMiddleware

Crearemos un middleware para redireccionar al usuario al perfil para que actualice su información cuando no haya definido aún biografía o avatar.

Aportes 49

Preguntas 20

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Yo creo qué se debería agregar el @login_required para verificar que el usuaria ya debe de esta logeado.

@login_required
def update_profile(request):
    """Update a user's profile view"""
    return render(request, 'users/update_profile.html')
def __call__(self, request):
        
        if not request.user.is_anonymous:
            
            #valida que el usuario sea administrador y permite que la solicitud continue
            if request.user.is_superuser:
                return self.get_response(request)
            
            #verifica el perfil del usuario 
            profile = request.user.profile
            if not profile.picture or not profile.biography:
                if request.path not in [reverse('update_profile'), reverse('logout')]:
                    return redirect('update_profile')

        response = self.get_response(request)
        return response 

Si su usuario no tiene un profile en la base (por ejemplo su super usuario) y tratan de entrar con ese, les marcará un error en el middleware, pueden agregar un try para que pruebe que exista un profile y si no que los lleve a la página de logeo:

    if not request.user.is_anonymous:
      try:
        profile = request.user.profile
        if not profile.picture or not profile.biography:
          if request.path != reverse('update_profile'):
            return redirect('update_profile')
      except:
        print('no profile')
        logout(request)
        return render(request, 'users/login.html', {'error': 'User has no profile'})

    response = self.get_response(request)
    return response

sale bye

Creo que esta imagen ayuda mucho más a entender el ciclo de vida request-response en Django

rnevius

Hook: Es un mecanismo que se utiliza para modificar un comportamiento original de un programa.

Es curioso el middleware aplica hasta en el admin

Para aquellos que les sale el error RelatedObectDoesNotExist al intentar hacer algo con un usuario sin profile:
.

from django.core.exceptions import ObjectDoesNotExist


De esta manera si el usuario no tiene perfil por algún motivo, se le crea uno y luego sera redirigido a nuestra view update_profile.

Tengo el siguiente problema, creo que intente trabajar con un usuario que no tenía perfil creado y no me deja continuar.

¿Debo crear el usuario manualmente para poder continuar?, ¿No debería la aplicación enviarme a la url de 'update_profile?.

Muchas gracias por su ayuda.

middleware.py

"""platzigram middleware catalog"""
#django
from django.shortcuts import redirect
from django.urls import reverse

class ProfileCompletionMiddleware:
  """Profile completion middleware
  Ensure every user is interacting with the 
  platform have their profile picture and biography
  """
  def __init__(self,get_response):
    """Middleware initialization"""
    self.get_response= get_response

  def __call__(self,request):
    """Code to be executed for each request before the view is called"""
    if not request.user.is_anonymous:
      profile = request.user.profile
      if not profile.picture or not profile.biography:
        if request.path !=  reverse('update_profile'):
          return redirect('update_profile')

    response= self.get_response(request)
    return response```

¿Qué es un Middleware? verás, en términos simples podemos definir un Middlawere cómo una pieza de código la cual se ejecutará antes y/o después de cada petición realizada al servidor.
.
.
Lo interesante de los middlewares en Django es que estos tiene la posibilidad de modificar la petición antes que esta llegue a la vista, y claro antes que el template sea renderizado. Esto nos permite, no solo agregar funcionalidad extra a las vistas, si no poder realizar diferentes validaciones sobre cada una de las peticiones al servidor, ya sea con fines de seguridad o simple debug.

Hola tengo un problea: cuando instalo el middleware me aparece el mimso problema que el profesor con los nombres, y aunque tengo bien el auth me sigue tomando mal.
El error:

django.core.exceptions.ImproperlyConfigured: WSGI application 'juanigram.wsgi.application' could not be loaded; Error importing module.
# Lista de middleware
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'juanigram.middleware.ProfileCompletionMiddleware',
]

El archivo se llama middleware y esta en el proyecto juanigram. Y para verificar que sean los mismo nombres copie y pegue.

Una aclaracion que no vi que la hiciera es que este middleware que hicimos aplica para todas las urls, por lo que si quisieran entrar a la url de “/admin/” les va a redireccionar, a la pagina que pusieron en el Middleware. Hay información sobre como saltarse el middleware para ciertos urls 😃

para que me jalara el request.user.profile tuve que agregar en Profile rl related name= profile

despues de Instalar el middleware me sale esto
en el navegador

La página no está redirigiendo adecuadamente

Firefox ha detectado que el servidor está redirigiendo la solicitud a esta dirección de una manera en la que nunca terminará.

    Este problema a veces está causado por desactivar o rechazar la 	 recepción de cookies.

Me gustaría entender más a que refiere reverse cuando y por qué usarlo

Los middlewares son llamados antes y después de la petición

El middleware tambien debe checar que no estemos intentando entrar a la vista de cerrar sesión, ya que como está escrito un usuario sin foto no podrá cerrar sesión

Qué clase tan interesante, me gustó mucho

Para tener en cuenta al crear los middlewares:
-Django inicializa el middleware solo con el argumento get_response, por lo que no se debe usar init() requerir otros argumentos.

  • call() se llama una vez por solicitud, mientras que init() se llama solo una vez, cuando se inicia el servidor web.

Si necesitamos escribir una ruta relativa para encontrar un archivo, podemos usar reverse, en dónde podemos poner entre comillas, simplemente el nombre del archivo.

302 significa redirección.

Nuestro MiddleWare, puede ser una clase vacía, en la que ponemos, un constructor con el parámetro: get_response, y luego hacemos una variable de instancia que lo contenga, para la lógica de nuestro MiddleWare, solo tenemos que crear le método __call__.

Los MiddleWares, pueden ser puestos, prácticamente en cualquier parte, si estos son comunes, se dejan en una carpeta de commons middle wares, sin embargo si son pocos podemos dejarlos en la carpeta del proyecto.

Tenemos la capacidad de acceder al request y sus datos, gracias al authentication middle ware.

El orden de los middlewares, es bien importante.

Para configurar nuestro MiddleWare, tenemos que ir a settings.py a la constante MIDDLEWARES.

Lo interesante, es que podemos editar el process_view para editar la vista, o el process_exception, que nos permite manejar ciertas excepsiones.

Otra manera de crear un MidldleWare es creando clases

Lo que es importante de aclarar es la función o MiddleWare, es llamada antes y depués de la petición.

Un middleWare, se puede crear como un función, que conlleva otra, para modificar el request.

Los middlewares, son en pocas palabras: Es una serie hooks que modifican el HTTPRequest y el HTTPResponse antes de que lleguen a la vista y después de que salgan de la vista.

Una consulta el @ en el template que significado y funcionalidad tiene??

No pude correr el middleware en python 2.7 , hasta aqui todo me habia funcionado bien y creo que es un error en el settings pero no lo pude corregir si alguien le paso lo mismo me lo puede comentar , trabajo con python 2.7 por motivos de trabajo.

Entonces podriamos usar un middleware para chequear si esta logeado el usuario al igual que el decorador arriba de la view de posts, no?

Si sería bueno que tuvieran en cuenta la forma en cómo se redacta la descripción del vídeo, el texto está demasiado confuso.

estoy trabajando con windows y tengo instalado el python 3.6, uso el virtual env de python todo estaba muy bien hasta que me salio el error que indico a continuación:
from Crypto.PublicKey import RSA
ModuleNotFoundError: No module named 'Crypto’

alguien le salio este error y pueden decirme como lo solucionaron…Gracias

Si request user es anónimo quiere decir que se salta AuthenticationMiddleware?
Si es el caso y se enviara un “e-mail” con los encabezados adecuados e incluso con los que se espera
del emisor en reverse podría quedarse en un loop dentro del middleware.
O lo mas facil y cochino seria antes de regresar lo validar que no se halla pasado por
ese middleware con una bandera o algo.

Nos enseño un ejemplo básico, pero esto siento que tiene infinitos usos en una aplicación grande.

monte la practica tal cual como en el video pero en mi caso no funciono como se muestra

muchas gracias , investigare mas sobre middlewares, me gusto ese api

Buenas dias, tardes o noches a todos. Tengo una duda: En el archivo urls.py se agregan las rutas para las diferentes funciones, lo que no entiendo es como sabe Django que, por ejemplo, ‘users_views.signup’ hace referencia al archivo views de la carpeta users. De antemano muchas gracias.

Aun me sale el error del csrf token, pero cuando hago refresh a la pagina entro normal a posts, alguien sabe porque?

quedo bastante claro el tema de middleware

En el middleware no puedo acceder a request.user.profile, que debo hacer para acceder al profile??
Puedo acceder a request.user.id, request.user.username, etc. Estoy usando python 3.8.2 y django 3.0.4

Wao!Acaba de enseñar algo tan increible

El Middleware que se agrega al proyecto queda automáticamente habilitado para todas las rutas? Es posible agregar el middleware a las rutas que queramos y no a todas. Hay una forma adicional a usar “reverse”?

excelente que cool

buen ejercicio,. gracias Pablo

Aqui una lo adecue un poco para que fuera mas legible, que opinan?

class ProfileCompletionMiddleware:
    """
    Profile completion middleware.

    Ensure every user that is interacting with the platform
    have their profile picture and biography.

    """
    def __init__(self, get_response):
       """Middleware initialization."""
       self.get_response = get_response

    def __call__(self, request):
        """Code to be executed for each request before the view is called."""

        user = request.user
        path = request.path
        if not request.user.is_anonymous:
            try:
                profile = user.profile
                if not self.profile_have_picture(profile) or not self.profile_have_biography(profile):
                    self.validate_path(path)
            except:
                logout(request)
                return render(request, 'users/login.html', {'error': 'User has no profile'})

        response = self.get_response(request)
        return response

    def path_is_admin(self, path):
        return path.startswith('/admin/')

    def profile_have_picture(self, profile):
        return True if profile.picture else False

    def profile_have_biography(self, profile):
        return True if profile.biography else False

    def validate_path(self, path):
        if path not in [reverse('update_profile'), reverse('logout')] and self.path_is_admin(path):
            return redirect('update_profile')```