django:目的django.utils.functional.SimpleLazyObject? [英] django: Purpose of django.utils.functional.SimpleLazyObject?

查看:1747
本文介绍了django:目的django.utils.functional.SimpleLazyObject?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I ran into an issue where I assigned request.user to a variable called prior_user, then essentially authenticated the user, then checked to see if request.user != prior_user. I expected them not to be the same and that prior_user should contain `AnonymousUser. To my surprise, they were the same.

示例代码:

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的实例,所以我假设它是某种懒惰的查找类型的事情,即before_user的值不会被查找直到实际使用。看看源代码,我无法确认这一点。

I then discovered prior_user actually contains an instance of django.utils.functional.SimpleLazyObject so I assume it is some sort of lazy lookup type thing i.e. prior_user's value isn't looked up until actually used. Looking at the source code, I cannot confirm this.

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

Anyone with django experience can tell me what is going on and why it is needed?

这让我有点动摇,因为通常的赋值语句不能像我所期望的那样工作,Django还有什么行为呢?在文档中也没有看到这一点。

This leaves me a little shaken, because the usual assignment statement doesn't work the way I expect and what else within Django acts like this? Nor did I see this described in the docs.

所以,超人类对django知识的人可以提供一些清晰度?

So anyone with super human knowledge of django can provide some clarity?

推荐答案

code> auth 中间件将用户属性添加到请求 SimpleLazyObject SimpleLazyObject ,本身是 LazyObject 的子类。

The auth middleware adds a user attribute to request that is an instance of SimpleLazyObject. SimpleLazyObject, itself is a subclass of LazyObject. LazyObject is, as described by the actual code:


另一个类的包装器 c> LazyObject 可以用于延迟包装类的实例化

A wrapper for another class that can be used to delay instantiation of the wrapped class

SimpleLazyObject 只设置通过传递的方法,该类( _wrapped 属性 LazyObject ),在这种情况下, GET_USER 。以下是该方法的代码:

SimpleLazyObject merely sets that class (the _wrapped attribute on LazyObject) via a passed in method, in this case, get_user. Here's the code for that method:

def get_user(request):
    if not hasattr(request, '_cached_user'):
        request._cached_user = auth.get_user(request)
    return request._cached_user

这本身就是一个围绕 auth.get_user 的包装器,它实现了一种缓存机制。所以这里是最终运行的:

That in itself is really just a wrapper around auth.get_user, that enables a sort of caching mechanism. So here's what actually is eventually run:

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 ,但如果您进行身份验证,然后访问它,则返回一个实例的用户

So, all that's really going on here is that request.user is ambiguous until it's actually used for something. This is important, because it allows it to adapt depending on the current authentication status. If you access a property on it before you authenticate, it returns an instance AnonymousUser, but if you authenticate and then access it, it returns an instance of User.

这篇关于django:目的django.utils.functional.SimpleLazyObject?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆