request.user返回一个SimpleLazyObject,我该如何“唤醒”它?
我有以下的方法:
def _attempt(actor): if actor.__class__ != User: raise TypeError
从视图中调用:
self.object.attempt(self.request.user)
正如你所看到的,_attempt方法期望actor是typesdjango.contrib.auth.models.User
,但是该对象看起来是django.utils.functional.SimpleLazyObject
types的。 这是为什么? 更重要的是,如何将LazyObject
(显然是一种用户对象的包装)转换成一个User
对象?
有关Request.user
更多信息,请访问: https : //docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.user此文档似乎表明request.user
应该是User
对象…
======进行后期编辑=====
我现在有以下方法:
def _attempt(obj, action, actor, msg): actor.is_authenticated() if isinstance(actor, LazyObject): print type(actor)
我传递一个用户,但是if
条件仍然是真的,actor仍然是一个LazyObject
。 这是为什么?
看到我的答案在类似的问题 。
Django懒加载request.user
以便它可以是User
或AnonymousUser
User
取决于身份validation状态。 它只是“唤醒”,并返回适当的类,当一个属性被访问。 不幸的是, __class__
不计数,因为这是一个原始的类属性。 在某些情况下,您可能需要知道这实际上是SimpleLazyObject
types,因此将其代理到User
或AnonymousUser
将是错误的。
总之,你根本无法做这个比较,因为你有它。 但是,你真的想在这里做什么? 如果你想要检查它是一个User
还是AnonymousUser
,那么就有request.user.is_authenticated()
。
一般来说,你不应该滥用鸭子打字。 一个参数应该总是一个特别的types或者子types( User
或者UserSubClass
),即使它不是必须的 。 否则,你最终会遇到困惑和脆弱的代码。
这应该做到这一点:
# handle django 1.4 pickling bug if hasattr(user, '_wrapped') and hasattr(user, '_setup'): if user._wrapped.__class__ == object: user._setup() user = user._wrapped
我不得不写这个,所以我可以添加一个用户到会话字典。 (SimpleLazyObjects不可挑选!)
user= request.user._wrapped if hasattr(request.user,'_wrapped') else request.user
然后你使用user
而不是request.user
。
这与UsAaR33的答案类似,但单一线程更适合转换对象。
对于任何想为你的代码写一个失败的“小”unit testing的人,你可以生成一个包装好的User
并将其填入请求中。
from django.contrib.auth import get_user_model from django.test import RequestFactory from django.utils.functional import SimpleLazyObject user = get_user_model().objects.create_user( username='jacob', email='jacob@…', password='top_secret', ) factory = RequestFactory() request = factory.get('/') request.user = SimpleLazyObject(lambda: user)
看到: