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)
- Solicita una URL que no tiene una barra inclinada. Así que
yourdomain.com/view
. Esto inicia el flujo de middleware. - Una vez que la solicitud llega a
CommonMiddleware
, el middleware ve que no hay una barra inclinada y devuelvehttp.HttpResponsePermanentRedirect(newurl)
. Esto inmediatamente detiene la ejecución de cualquierprocess_requests
de proceso adicional, incluido uno enAuthenticationMiddleware
que agrega el atributo deuser
pararequest
- Como
CommonMiddleware
no devolvió una excepción (incluidoHttp404
),django
ahora tomará la respuesta del middleware y la ejecutará a través de CADAprocess_response()
en CADA middleware listado enMIDDLEWARE_CLASSES
, sin importar si el middlewareprocess_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