2012-05-08 33 views
41

request.user'u prior_user adlı bir değişkene atandım, daha sonra kullanıcının kimliğini doğruladım, sonra request.user != prior_user olup olmadığını kontrol ettim. Onları aynı olmamasını ve prior_user'un "AnonymousUser" içermesi gerektiğini umdum. Benim için sürpriz oldu.django: django.utils.functional.SimpleLazyObject'in amacı nedir?

örnek kod: Sonra prior_user aslında django.utils.functional.SimpleLazyObject bir örneğini içeren keşfetti

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 i.e.they are the same! 

yüzden yani prior_user değeri baktım değil tembel arama tipi şey bir tür olduğunu varsayalım Gerçekten kullanılana kadar. Kaynak koduna baktığımda, bunu doğrulayamıyorum.

Django deneyimi olan herkes bana neler olduğunu ve niçin gerekli olduğunu söyleyebilir mi?

Bu beni biraz sarsar, çünkü olağan atama bildirimi beklediğim şekilde çalışmıyor ve Django'nun içinde başka ne gibi davranıyor? Bunu, docs'da açıklandığı gibi görmedim.

Django süper insan bilgisi olan herkes biraz netlik sağlayabilir mi?

cevap

97

auth ara katman yazılımı, SimpleLazyObject'un bir örneğidir, request için bir user özniteliği ekler. SimpleLazyObject, kendisi LazyObject'un bir alt sınıfıdır.

sarılmış sınıf örneğinin geciktirmek için kullanılabilen başka bir sınıf için bir sarıcı

SimpleLazyObject sadece (LazyObject üzerinde _wrapped özniteliği), sınıf belirler

: gerçek kod tarif edildiği gibi LazyObject olduğu Bu yöntemde geçen bir yöntemle, get_user. İşte bu yöntem için kod: kendi içinde gerçekten önbelleğe alma mekanizmasının bir çeşit sağlayan bir sarıcı etrafında auth.get_user olduğu

def get_user(request): 
    if not hasattr(request, '_cached_user'): 
     request._cached_user = auth.get_user(request) 
    return request._cached_user 

O. Yani burada aslında nihayetinde çalıştırmak ne:

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 

Yani, tüm bu gerçekten burada oluyor aslında bir şey için kullanılan kadar request.user belirsiz olmasıdır. Bu önemlidir, çünkü geçerli kimlik doğrulama durumuna bağlı olarak adapte olmasına izin verir.'dan önce üzerinde bir özelliğe erişirseniz, kimlik doğrulaması yaparsanız, AnonymousUser örneğini döndürür, ancak kimlik doğrulamasını yapar ve ona erişirse, User örneğini döndürür.

+3

Teşekkür ederim, bu benim gibi bir django acemi için çok yardımcı oldu! Büyük açıklama için – donogood

+4

+1! – Anoyz