【问题标题】:django: Purpose of django.utils.functional.SimpleLazyObject?django:django.utils.functional.SimpleLazyObject 的目的?
【发布时间】:2012-05-17 10:01:54
【问题描述】:

我遇到了一个问题,我将request.user 分配给一个名为prior_user 的变量,然后基本上验证了用户,然后检查是否request.user != prior_user。我希望它们不一样,prior_user 应该包含 `AnonymousUser.令我惊讶的是,它们是一样的。

示例代码:

prior_user = request.user   # request object, obtained froma  view
authenticate_user(request)   # some function that authenticates
print prior_user.username != request.user.username   # returns False i.e.they are the same!

然后我发现prior_user实际上包含一个django.utils.functional.SimpleLazyObject的实例,所以我认为它是某种惰性查找类型的东西,即在实际使用之前不会查找prior_user的值。查看源代码,我无法确认。

任何有 django 经验的人都可以告诉我发生了什么以及为什么需要它?

这让我有点动摇,因为通常的赋值语句不能按我期望的方式工作,而 Django 中还有什么东西是这样的?我也没有在docs 中看到这一点。

那么任何对 django 有超人了解的人都可以提供一些清晰的信息吗?

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    auth 中间件将user 属性添加到request,它是SimpleLazyObject 的一个实例。 SimpleLazyObject,本身是LazyObject 的子类。 LazyObject 是,如实际代码所述:

    另一个类的包装器,可用于延迟被包装类的实例化

    SimpleLazyObject 仅通过传入的方法设置该类(LazyObject 上的_wrapped 属性),在本例中为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 的实例。

    【讨论】:

    • 我怀疑 django 中的惰性对象和 python 中的惰性对象代理(pypi.org/project/lazy-object-proxy)是否相同??
    • 也如你所说 SimpleLazyObject 是 LazyObject 的子类,那么两者有什么区别??
    猜你喜欢
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2014-01-30
    • 2011-09-26
    • 2019-12-17
    • 2017-12-26
    • 2015-04-21
    相关资源
    最近更新 更多