crear python django wsgi django-middleware

python - crear - Django: ¿El objeto WSGIRequest ''no tiene atributo'' usuario ''en algunas páginas?



crear middleware django (6)

Quiero configurar una cookie si el usuario está conectado o no.

Mi Middleware:

class UserStatus(object): def process_response(self,request,response): user_status = 1 if request.user.is_authenticated() else 0 max_age = (20)*52*7*24*60*60 # 20 years (After expiry, cookie gets deleted) response.set_cookie(user_status_cookie,user_status,max_age) return response

Agregado a MIDDLEWARE_CLASSES en settings.py al final.

Problema:

  • Error: el objeto ''WSGIRequest'' no tiene ningún atributo ''usuario''
  • ¿Por qué, cuando ya tengo activadas la autenticación y los middlewares de sesión?
  • Además, algunas páginas funcionan sin problemas, ya que algunas están dando este error.
  • Qué estoy haciendo mal ?

Por favor ayuda.


¿tienes activo este middleware ?:

''django.contrib.auth.middleware.AuthenticationMiddleware''

Y este middleware se ejecuta antes de su middleware?


De acuerdo con el FineManual:

Durante las fases de respuesta (process_response () y process_exception () middleware), las clases se aplican en orden inverso, de abajo hacia arriba

Así que diría que es mejor que agregue su middleware antes de los middlewares de autenticación y sesión (suponiendo que solo procese la respuesta).

Dicho esto, estoy un poco desconcertado por el hecho de que solo tienes el error en algunas páginas ???


Podría haber una excepción planteada dentro de algún middleware o cualquier otro código que se ejecute antes del AuthenticationMiddleware de django (que es responsable de asignar el .user al objeto request).

Luego habrá un AttributeError al acceder a la variable .user.

Por ejemplo, cualquier excepción activada antes de que AuthenticationMiddleware tuviera la oportunidad de ejecutarse podría provocar la ejecución de la vista de error. Obtendrá el error mencionado en el título de la pregunta, si la vista de error depende de request.user.


Por lo tanto, tiene que ver con la aplicación de APPEND_SLASH a través de una redirección de Django Common Middleware, evitando que process_request() en AuthenticationMiddleware (que agrega el atributo de user ) se ejecute pero que su process_response aún se esté ejecutando.

Así es como realmente funciona Django Process Middleware (desde django/core/handlers/base.py en Django 1.6)

  1. Solicita una URL que no tiene una barra inclinada. Así que yourdomain.com/view . Esto inicia el flujo de middleware.
  2. Una vez que la solicitud llega a CommonMiddleware , el middleware ve que no hay una barra inclinada y devuelve http.HttpResponsePermanentRedirect(newurl) . Esto inmediatamente detiene la ejecución de cualquier process_requests de proceso adicional, incluido uno en AuthenticationMiddleware que agrega el atributo de user para request
  3. Como CommonMiddleware no devolvió una excepción (incluido Http404 ), django ahora tomará la respuesta del middleware y la ejecutará a través de CADA process_response() en CADA middleware listado en MIDDLEWARE_CLASSES , sin importar si el middleware process_request() tuvo la oportunidad de ejecutarse.

La única manera real de solucionar esto es mover el código en un método process_request() ubicado después de AuthenticationMiddleware en MIDDLEWARE_CLASSES o detectar mediante hasattr() si el objeto de request tiene un atributo de user .


Se topó con el mismo problema recientemente, y descubrió que sucedía cuando se accede a una url sin la barra al final, y la configuración de APPEND_SLASH está establecida en verdadero:

Django procesa la solicitud inicial

  • CommonMiddleware.process_request
    • Redirige a newurl, que tiene la barra inclinada
  • process_response aún se ejecuta en middleware personalizado
    • request.user no está presente
  • HTTP 301

Django luego procesa la solicitud de url con barra inclinada

  • process_response se ejecuta en middleware personalizado
    • request.user ahora está presente

¿Alguien sabe por qué algunos de los atributos principales (usuario y sesión) no están accesibles en process_response después de una redirección permanente?


Tuve un problema similar, algunas de mis páginas no tienen al usuario en la solicitud, así que en mi middleware hago un control rápido

if not hasattr(request, ''user''): return response