2011-06-29 26 views
9

Django'da auth_user sınıfı için özel bir yönetici nasıl kullanabilirim?UserManager'ı django'ya geçersiz kılma

Django projemde auth_user kullanıyorum ve temel bir profil sınıfına sahibim. Sitemin her sayfasında, bazı kullanıcı ve profil verilerini kullanıyorum, bu yüzden her kullanıcı sorgusu profile katılmalıdır.

Özel bir yöneticide get_query_set() yönteminde select_related yöntemini kullanmak istedim, ancak birini tanımlamak veya mevcut UserManager'u geçersiz kılmak için uygun bir yol bulamıyorum. Herhangi bir fikir?

Not: Kullanıcı modelini geçersiz kılmak istemiyorum. Ya da daha kesin olmak gerekirse, onu farklı proxy modellerinde zaten geçersiz kıldım. Bu özel yöneticinin her proxy modelinde kullanılmasını istiyorum.

cevap

6

Tamam, sonunda doğru cevabı buldum. En temiz yol, özel bir kimlik doğrulama arka ucunu kullanmaktır.

# in settings: 
AUTHENTICATION_BACKENDS = ('accounts.backends.AuthenticationBackend',) 


# in accounts/backends.py: 
from django.contrib.auth.backends import ModelBackend 
from django.contrib.auth.models import User 


class AuthenticationBackend(ModelBackend): 
    def get_user(self, user_id): 
     try: 
      # This is where the magic happens 
      return User.objects. \ 
       select_related('profile'). \ 
       get(pk=user_id) 
     except User.DoesNotExist: 
      return None 
3

Bu oldukça çirkindir, ancak muhtemelen Kullanıcı objects özelliğine sahip olabilirsiniz. Bir katman içinde:

# manager.py 
from django.contrib.auth.models import UserManager 

class MyUserManager(UserManager): 
    def get_query_set(self): 
     qs = super(MyUserManager, self).get_query_set() 
     return qs.select_related('profile') 

# middleware.py 
from django.contrib.auth.middleware import AuthenticationMiddleware 
from managers import MyUserManager 

class MyAuthMiddleware(AuthenticationMiddleware): 
    def process_request(self, request): 
     super(AuthenticationMiddleware, self).process_request(request) 
     User.objects = MyUserManager() 
     return None 

Sonra settings.py satırı değiştirin:

MIDDLEWARE_CLASSES = (
    # ... 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    # ... 
) 

Tarafından:

# settings.py 
MIDDLEWARE_CLASSES = (
    # ... 
    'yourapp.middleware.MyAuthMiddleware', 
    # ... 
) 

Not 1: Bu kod, salt teorik test asla ya da zamanım var.

Not2: Bu çözümü uzun vadeli bir bakım açısından kullanmanızı öneriyorum.

Not3: Birisi başka bir şey önerirse, muhtemelen onu benden daha çok dinlemelisiniz.

Not4: Muhtemelen daha iyi bir fikir olarak, neden toplam denetime sahip olduğunuz bir model sınıfı olan Profil için sorgulamaya çalışmamanız gerekir? Kullanıcı nesnesini her zaman bir profilden alabilirsiniz, böylece…

+0

Daha temiz bir yol bulamadığım için bu cevabı kabul edeceğim. Bununla birlikte, django BT'de bir hata raporu doldurdum. Bekle ve gör. https://code.djangoproject.com/ticket/16379 –

+3

Bu cevabı gerçekten kabul etmemelisiniz, çünkü yeni başlayanlar, sizin geliştirdiğiniz problemi çözmek için kabul edilebilir bir yaklaşım olduğu sonucuna varabilirler. – NiKo

+0

Denedim ve işe yaramadı ... Benim için basit bir çözüm olurdu – James