0

My understanding and experience is that request.user in Django returns an object of type SimpleLazyObject. How do I obtain an object of type Userusing this SimpleLazyObject

In particular this is my derived User model

models.py

class UserInfo(User):
mobile_number = models.CharField(max_length=10, null=False, blank=False)
purchase_code = models.CharField(max_length=25, null=False, blank=False)

REQUIRED_FIELDS = ['first_name', 'last_name', 'mobile_number', 'password', 'purchase_code']

def clean(self):
    self.username = str(self.mobile_number)

I have written the following function which seems to work perfectly fine except that I have to make a database query. Is there a better way of getting an instance of the currently logged in User?

# This is a function to obtain the current logged in user. In case no one has logged-in the function
# returns an instance of the class AnonymousUser
def get_user(request):
    current_user = request.user #auth.get_user(request)
    if type(current_user) is not AnonymousUser:
        current_user = UserInfo.objects.get(pk=auth.get_user(request).pk)
    return HttpResponse(current_user)
hkalra
  • 55
  • 1
  • 6
  • 1
    you're trying use custom User class, if that's the case have a look at https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#substituting-a-custom-user-model – sha256 Oct 26 '14 at 11:56

2 Answers2

3

SimpleLazyObject will resolve to the actual User object when you first access one of its properties. Also, no need to check the type of the returned user, because you can ask it directly whether or not it's an anonymous user.

def my_view(request):
    user = request.user
    if user.is_anonymous():
        # do something as an anonymous user
    else:
        return HttpResponse(user.username)

Forget about the actual object being of the type SimpleLazyObject. It is an optimisation. The object you're accessing is going to be the User instance you expect.

Josh Smeaton
  • 47,939
  • 24
  • 129
  • 164
  • Hi Josh, Thanks for your quick response. My use-case requires me to obtain an object of type `Userinfo` which is essentially a child of the class `User`. Your code works perfectly if I try to access an attribute like `username` which belongs to the parent class but fails if I try to access `mobile_number` with the following error message - _'User' Object has no attribute 'mobile_number'_. Any suggestions? – hkalra Oct 26 '14 at 10:48
  • 2
    @hkalra someone has already answered your second question in the comments to your original question. You need to read all the docs regarding custom user models. – Josh Smeaton Oct 26 '14 at 23:29
1

It is recommended to extend the User model by using a one to one relationship

class UserInfo(models.Model):
    user = models.OnetoOneField(User, related_name="user_info")
    ...

The related_name attribute defines the name of relation reverse relation from the User model to your custom user model. It is explained here

Now you access UserInfo's fields like this

request.user.user_info.mobile_number

Also like Josh pointed out, you can get the default User model fields like this

request.user.username

Community
  • 1
  • 1
Abhinav
  • 622
  • 6
  • 15