Ответ 1
Среднее ПО auth
добавляет атрибут user
к request
, который является экземпляром SimpleLazyObject
. SimpleLazyObject
, сам по себе является подклассом LazyObject
. LazyObject
, как описано в фактическом коде:
Обертка для другого класса, которая может использоваться для задержки создания экземпляра завернутого класса
SimpleLazyObject
просто устанавливает этот класс (атрибут _wrapped
на LazyObject
) через переданный метод, в данном случае get_user
. Здесь код для этого метода:
def get_user(request):
if not hasattr(request, '_cached_user'):
request._cached_user = auth.get_user(request)
return request._cached_user
Это само по себе является всего лишь оберткой вокруг auth.get_user
, что позволяет использовать механизм кэширования. Итак, вот что на самом деле в конечном итоге запускается:
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
Итак, все, что действительно происходит здесь, состоит в том, что request.user
неоднозначно, пока оно фактически не используется для чего-то. Это важно, так как позволяет ему адаптироваться в зависимости от текущего состояния аутентификации. Если вы получаете доступ к свойству на нем перед аутентификацией, он возвращает экземпляр AnonymousUser
, но если вы аутентифицируете и затем обращаетесь к нему, он возвращает экземпляр user
.