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?
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.