request.user返回SimpleLazyObject,我该如何“唤醒”了吗?(request

2019-06-26 00:29发布

我有以下方法:

def _attempt(actor):
    if actor.__class__ != User:
        raise TypeError

这是从视图叫:

self.object.attempt(self.request.user)

正如你所看到的,_attempt方法希望演员是类型django.contrib.auth.models.User ,但对象似乎是类型django.utils.functional.SimpleLazyObject 。 为什么会这样? 更重要的是,我怎么能转换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条件仍然为真,演员仍是一个LazyObject 。 为什么会这样?

Answer 1:

请参见上一个类似的问题我的答案 。

Django的延迟加载request.user ,以便它可以是UserAnonymousUser根据认证状态。 它只是被“唤醒”,当一个属性上它访问返回相应的类。 不幸的是, __class__不计,因为这是一个原始的类属性。 有场合,你可能需要知道,这其实是一个SimpleLazyObject类型,因此这将是错误的代理它给UserAnonymousUser

长与短,你根本无法为你拥有了它这样做比较。 但是,什么是你真正想在这里实现? 如果你想检查它是否是一个UserAnonymousUser ,还有的request.user.is_authenticated()的,例如。

虽然作为一般规则,你不应该滥用鸭打字。 一个参数应始终是一个特别类型或子类型( UserUserSubClass ),尽管它并不必须如此。 否则,你结束了混乱和脆弱的代码。



Answer 2:

这应该这样做:

# 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不picklable!)



Answer 3:

user= request.user._wrapped if hasattr(request.user,'_wrapped') else request.user

然后使用user ,而不是request.user

这类似于UsAaR33的答案,而是一个班轮是用于转换对象更好。



Answer 4:

对于任何人想要写你的代码,一个失败的“小”单元测试,您可以生成一个包裹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)

看到:

  • https://github.com/django/django/blob/master/tests/utils_tests/test_lazyobject.py有关懒惰对象电流测试。

  • https://docs.djangoproject.com/en/dev/topics/testing/advanced/#django.test.RequestFactory的最新信息RequestFactory



文章来源: request.user returns a SimpleLazyObject, how do I “wake” it?