Request.user returns a SimpleLazyObject, how to wake it up?

I have the following method:

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

What is called from the view:

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

As you can see, the _attempt method assumes that the actor will be of type django.contrib.auth.models.User , however the object looks like the type django.utils.functional.SimpleLazyObject . Why is this so? And more importantly, how can I convert a LazyObject (which is apparently a kind of wrapper for the User object) to a User object?

Additional information about Request.user is available here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.user This documentation states that Request.user must be a User object ...

====== after editing =====

Now I have the following method:

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

I pass the user, however, if condition is still true, the actor is still LazyObject . Why is this so?

+45
python django django-users django-contrib
Jul 03 2018-12-12T00:
source share
4 answers

See my answer on a similar question .

Django lazy load request.user so that it can be either User or AnonymousUser depending on the state of authentication. It only wakes up and returns the corresponding class when an attribute accesses it. Unfortunately, __class__ not taken into account because it is a primitive attribute of the class. Where you may need to know that it is indeed a SimpleLazyObject type, and therefore it would be incorrect to proxy it to User or AnonymousUser .

Long and short, you simply cannot make this comparison as you have. But what are you really trying to achieve here? If you are trying to check whether there is a User or AnonymousUser , there is request.user.is_authenticated() for this, for example.

Generally, you should not abuse duck printing. The parameter should always be a particularly type or subtype ( User or UserSubClass ), although this is optional. Otherwise, you will get confused and fragile code.

+31
Jul 03 '12 at 17:00
source share

This should do it:

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

I had to write this to add the user to the session dictionary. (SimpleLazyObjects are not matched!)

+13
Nov 09 '12 at 8:14
source share
 user= request.user._wrapped if hasattr(request.user,'_wrapped') else request.user 

Then you use user instead of request.user .

This is similar to UsAaR33's answer, but single-line mode is better for transforming an object.

+9
Apr 30 '13 at 16:29
source share

For those who want to write an unsuccessful β€œsmall” unittest for your code, you can create a wrapped User and fill it inside the request.

 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) 

Cm:

0
Dec 15 '16 at 19:22
source share



All Articles