Search code examples
djangodjango-authenticationdjango-sessions

What is the purpose of Django's request._cached_user?


New to Django and really trying to build a solid grasp of its built-in authentication and session mechanisms. Looking in the current (v1.8) source code, I see this:

django/contrib/auth/middleware.py

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

class AuthenticationMiddleware(object):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE_CLASSES setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        )
        request.user = SimpleLazyObject(lambda: get_user(request))

When I grep through the Django code, I don't see anywhere else that request._cached_user is referenced, and nowhere else that this particular get_user() is called besides the lambda in the auth middleware. Unless I don't understand middleware, the process_request() is only called once per request.

Am I missing an obvious reason why Django is storing _cached_user in request, never to reference it again?


Solution

  • As part of the general Django MVC pattern, Views are passed Requests (not logged in users).

    However accessing the authenticated User model is a frequent operation in any Django apps that use login/authentication.

    The framework (and in particular the AuthenticationMiddleware) assumes that the authenticated User associated with a Request will not change during the handling of each web request.

    For performance reasons, the get_user function retains a reference the associated User and thus avoids repeat database queries for the associated User.