django:django.utils.functional.SimpleLazyObject的目的是什么?
我遇到了一个问题,我把request.user
分配给了一个名为prior_user
的variables,然后对用户进行了基本的validation,然后检查了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 iethey are the same!
然后,我发现prior_user实际上包含一个django.utils.functional.SimpleLazyObject的实例,所以我认为它是某种懒惰的查找types的东西,即prior_user的价值是不查找,直到实际使用。 看源代码,我无法证实这一点。
任何有Django经验的人都可以告诉我发生了什么,为什么需要这样做?
这让我有点动摇,因为通常的赋值语句不能像我期望的那样工作,Django中的其他内容也是这样吗? 我也没有看到在文档中描述的这一点。
所以任何拥有django超级人类知识的人都可以提供一些清晰度?
auth
中间件添加一个user
属性来request
这个SimpleLazyObject
的实例。 SimpleLazyObject
本身是LazyObject
的子类。 LazyObject
就像实际的代码所描述的那样:
另一个类的包装器,可以用来延迟包装类的实例化
SimpleLazyObject
只是通过一个传入的方法(在本例中为get_user
)来设置该类( _wrapped
上的_wrapped
属性)。 这是该方法的代码:
def get_user(request): if not hasattr(request, '_cached_user'): request._cached_user = auth.get_user(request) return request._cached_user
这本身实际上只是auth.get_user
一个包装,它启用了一种caching机制。 那么这里是最终运行的是什么:
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
在用于某些事情之前是不明确的。 这很重要,因为它可以根据当前的身份validation状态进行调整。 如果您在进行身份validation之前访问其上的属性,它将返回一个实例AnonymousUser
,但是如果您进行身份validation并访问它,则会返回一个User
的实例。