programing

request.user는 SimpleLazyObject를 반환합니다. 어떻게 "깨우기"합니까?

yoursource 2021. 1. 15. 19:52
반응형

request.user는 SimpleLazyObject를 반환합니다. 어떻게 "깨우기"합니까?


다음과 같은 방법이 있습니다.

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

뷰에서 호출됩니다.

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

보시다시피 _attempt 메소드는 액터가 type django.contrib.auth.models.User것으로 예상 하지만 객체는 유형 인 것으로 보입니다 django.utils.functional.SimpleLazyObject. 왜 그렇습니까? 그리고 더 중요한 것은 어떻게 LazyObject(분명히 User 객체에 대한 일종의 래퍼 인) 객체를 객체로 변환 할 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둘 중 하나 일 수 있습니다 . 단지 "깨어나고"속성에 액세스 할 때 적절한 클래스를 반환합니다. 불행히도 기본 클래스 속성이기 때문에 계산되지 않습니다. 이것이 실제로 유형 이라는 것을 알아야 할 경우가 있으므로 또는 에 프록시하는 것은 잘못된 것 입니다.UserAnonymousUser__class__SimpleLazyObjectUserAnonymousUser

길고 짧게, 당신이 가지고있는 그대로이 비교를 할 수 없습니다. 하지만 여기서 정말로 달성하려는 것은 무엇입니까? 당신이이 있는지 확인하려는 경우 UserAnonymousUser, 거기에 request.user.is_authenticated()예를 들어, 그것을 위해.

하지만 일반적으로 덕 타이핑을 남용해서는 안됩니다. 매개 변수는 항상 (A는 특히 입력하거나 하위해야 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의 대답과 유사하지만 객체를 변환하는 데는 한 줄짜리가 더 좋습니다.


코드에 대해 실패한 "작은"단위 테스트를 작성하려는 사람을 위해 랩핑을 생성 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)

보다:

참조 URL : https://stackoverflow.com/questions/11314905/request-user-returns-a-simplelazyobject-how-do-i-wake-it

반응형