request.user devuelve un objeto SimpleLazyObject, ¿cómo lo “despierto”?

Tengo el siguiente método:

def _attempt(actor): if actor.__class__ != User: raise TypeError 

Lo que se llama desde una vista:

 self.object.attempt(self.request.user) 

Como puede ver, el método _attempt espera que el actor sea de tipo django.contrib.auth.models.User , sin embargo, el objeto parece ser de tipo django.utils.functional.SimpleLazyObject . ¿Por qué esto es tan? Y, lo que es más importante, ¿cómo puedo convertir LazyObject (que aparentemente es un tipo de envoltorio para un objeto Usuario) en un objeto User ?

Más información sobre Request.user está disponible aquí: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.user Esta documentación parece indicar que request.user debe ser un Objeto de User

====== Edición posterior =====

Tengo el siguiente método ahora:

 def _attempt(obj, action, actor, msg): actor.is_authenticated() if isinstance(actor, LazyObject): print type(actor) 

Estoy pasando un usuario, sin embargo, if condición sigue siendo cierta, el actor sigue siendo un LazyObject . ¿Por qué esto es tan?

Ver mi respuesta en una pregunta similar .

Django lazy carga request.user para que pueda ser User o User AnonymousUser según el estado de autenticación. Solo se “despierta” y devuelve la clase apropiada cuando se accede a un atributo en él. Desafortunadamente, __class__ no cuenta porque es un atributo de clase primitivo. Hay ocasiones en las que es posible que necesite saber que este es realmente un tipo SimpleLazyObject , y por lo tanto, sería incorrecto SimpleLazyObject un proxy al User o User AnonymousUser .

Largo y corto, simplemente no puedes hacer esta comparación como la tienes. Pero, ¿qué estás tratando de lograr realmente aquí? Si está intentando verificar si es un User o un User AnonymousUser , existe request.user.is_authenticated() para eso, por ejemplo.

Sin embargo, como regla general, no debes abusar de la escritura de pato Un parámetro siempre debe ser un tipo o subtipo particular ( User o UserSubClass ), aunque no tiene que serlo. De lo contrario, terminas con un código confuso y frágil.

Esto debería hacerlo:

 # handle django 1.4 pickling bug if hasattr(user, '_wrapped') and hasattr(user, '_setup'): if user._wrapped.__class__ == object: user._setup() user = user._wrapped 

Tuve que escribir esto para poder agregar un usuario al diccionario de la sesión. (SimpleLazyObjects no son seleccionables!)

 user= request.user._wrapped if hasattr(request.user,'_wrapped') else request.user 

Entonces usas user lugar de request.user .

Esto es similar a la respuesta de UsAaR33, pero una sola línea es mejor para convertir el objeto.

Para cualquier persona que desee escribir una prueba de unidad “pequeña” para su código, puede generar un User envuelto y rellenarlo dentro de una solicitud.

 from django.contrib.auth import get_user_model from django.test import RequestFactory from django.utils.functional import SimpleLazyObject user = get_user_model().objects.create_user( username='jacob', email='jacob@…', password='top_secret', ) factory = RequestFactory() request = factory.get('/') request.user = SimpleLazyObject(lambda: user) 

Ver: