запрос.пользователь возвращает SimpleLazyObject, как я могу "разбудить" его?

у меня есть следующий метод:

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

который называется с точки зрения:

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

как вы можете видеть, метод _attempt ожидает, что актер будет типом объект представляется типа django.utils.functional.SimpleLazyObject. Почему это так? И что еще более важно, как я могу преобразовать LazyObject (который, по-видимому, является своего рода оболочкой для объекта пользователя) в

4 ответов


посмотреть мой ответ на подобный вопрос.

Django ленивые нагрузки request.user Так что это может быть либо User или AnonymousUser в зависимости от состояния аутентификации. Он только "просыпается" и возвращает соответствующий класс, когда атрибут доступен на нем. К сожалению, __class__ не считается, потому что это атрибут примитивного класса. Есть случаи, когда вам нужно знать, что это на самом деле SimpleLazyObject тип, и поэтому было бы неправильно прокси-это на User или AnonymousUser.

длинный и короткий, вы просто не можете сделать это сравнение, как у вас есть. Но что ты такое!--19-->действительно пытаетесь достичь здесь? Если вы пытаетесь проверить, является ли это User или AnonymousUser, есть request.user.is_authenticated() для этого, например.

как общее правило, вы не должны злоупотреблять печатанием утки. Параметр всегда должен быть определенным типом или подтипом (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 не picklable!)


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

затем вы используете user вместо request.user.

Это похоже на ответ UsAaR33, но однострочный лучше для преобразования объекта.


для тех, кто хочет написать не "маленький" unittest для вашего кода, Вы можете создать завернутые 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)

посмотреть: