Django:为什么_cached_user是请求的实例属性,而LazyUser是请求的类属性?

时间:2011-05-10 04:27:07

标签: django django-authentication django-sessions

在Django中:

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

class LazyUser(object):
  def __get__(self, request, obj_type=None):
    if not hasattr(request, '_cached_user'):
        from django.contrib.auth import get_user
        request._cached_user = get_user(request)
    return request._cached_user

class AuthenticationMiddleware(object):
  def process_request(self, request):
    assert hasattr(request, 'session'), "The Django authentication ..."
    request.__class__.user = LazyUser()
    return None

正如您所看到的,_cached_userrequest实例的属性,而LazyUser()是请求类的属性:

request.__class__.user = LazyUser()

为何与众不同? LazyUser基本上只检查_cached_user是否存在,如果不存在,则会向session后端查询该用户。在这种情况下,LazyUser_cached_user不应该是实例request的属性吗?

1 个答案:

答案 0 :(得分:0)

request.__class__.user = LazyUser()

那是因为,您可以在视图和模板中使用已登录的用户实例,并且最好的位置是保持该数据的请求...

另一方面, _cached_user 是django的内部函数,也就是说,该函数在django中使用,并且必须是aviod才能被使用django的任何人使用。所以合乎逻辑的做法是不要把它作为一个类的attirbute ...正如django开发人员所说,属性始于' _'不得使用django中使用的写入,而不是任何用django编写的应用程序。

此外, _cached_user 检查请求,在某些情况下,登录用户的请求数据可能不包含该信息(例如因为浏览器缓存) LazyUser 保证在每种情况下都返回登录用户的用户实例。

Django假设在处理每个Web请求期间,与请求关联的经过身份验证的用户不会更改。