【问题标题】:Django - AuthenticationMiddleware setting request.userDjango - AuthenticationMiddleware 设置 request.user
【发布时间】:2013-03-02 11:24:40
【问题描述】:


关于AuthenticationMiddleware,为什么Django 1.3 在类级别处理user 属性, 为什么在 1.4 中改为实例属性?


这是从 1.3 开始的

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):
        request.__class__.user = LazyUser()
        return None


这是从 1.4 开始的

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'."

        request.user = SimpleLazyObject(lambda: get_user(request))
        # SimpleLazyObject inherits from LazyObject


在 1.3 中,我了解到 process_request 将 LazyUser() 分配给类级别的 user 属性,这对我来说基本上意味着两件事:

  • HttpRequest 类 (request.__class__) 在两个请求之间存储了其 user 属性,因此未来的 request 对象可以访问它。
  • 每当视图函数尝试访问request.user 时,都会触发LazyUser 对象的__get__ 方法并从请求的缓存或身份验证存储中返回一个用户对象。

我说的对吗?

另外,我在 1.4 中注意到了这两个主要变化:

  • SimpleLazyObject 分配给 request,而不是分配给它的类(因此,它是一个实例属性)。
  • LazyObject 和 SimpleLazyObject 不定义(自定义)他们自己的 __get__ 方法。

这样get_user什么时候触发?
AuthenticationMiddleware现在如何在两个请求之间存储request.user,并覆盖Http的无状态?

【问题讨论】:

标签: python django authentication django-middleware


【解决方案1】:

没有。这两个版本是等效的。不过 1.4 版本更简单。

过去是如何工作的

LazyUser 对象实现了descriptor protocol。

描述符理解起来有点绕,但是这里的大意是,虽然user是一个类属性,访问request.user会调用request.__class__.user.__get__(request),因此让__get__方法访问请求参数,它将用于返回绑定到请求的用户。

现在如何运作

user 属性使用SimpeLazyObject 构造来实现相同的目标:避免加载所有不需要的用户机器。

关于何时调用get_user:

当您访问request.user 上的属性时,例如request.user.attr1,将调用request.user.__getattr__('attr1'),然后调用request.user._setup(),最终调用get_user。

Django 如何创建状态

通过使用 Sessions。看看 django 的 session 中间件。

【讨论】:

    猜你喜欢
    • 2011-07-26
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多