django: Purpose of django.utils.functional.SimpleLazyObject?

后端 未结 1 1470
小鲜肉
小鲜肉 2020-11-30 23:48

I ran into an issue where I assigned request.user to a variable called prior_user, then essentially authenticated the user, then checked to see if

相关标签:
1条回答
  • 2020-12-01 00:26

    The auth middleware adds a user attribute to request that is an instance of SimpleLazyObject. SimpleLazyObject, itself is a subclass of LazyObject. LazyObject is, as described by the actual code:

    A wrapper for another class that can be used to delay instantiation of the wrapped class

    SimpleLazyObject merely sets that class (the _wrapped attribute on LazyObject) via a passed in method, in this case, get_user. Here's the code for that method:

    def get_user(request):
        if not hasattr(request, '_cached_user'):
            request._cached_user = auth.get_user(request)
        return request._cached_user
    

    That in itself is really just a wrapper around auth.get_user, that enables a sort of caching mechanism. So here's what actually is eventually run:

    def get_user(request):
        from django.contrib.auth.models import AnonymousUser
        try:
            user_id = request.session[SESSION_KEY]
            backend_path = request.session[BACKEND_SESSION_KEY]
            backend = load_backend(backend_path)
            user = backend.get_user(user_id) or AnonymousUser()
        except KeyError:
            user = AnonymousUser()
        return user
    

    So, all that's really going on here is that request.user is ambiguous until it's actually used for something. This is important, because it allows it to adapt depending on the current authentication status. If you access a property on it before you authenticate, it returns an instance AnonymousUser, but if you authenticate and then access it, it returns an instance of User.

    0 讨论(0)
提交回复
热议问题