django:目的django.utils.functional.SimpleLazyObject? [英] django: Purpose of 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屋!