2011-06-29 62 views
9

如何在django中使用auth_user類的自定義管理器?覆蓋django中的UserManager

在我的django項目中,我使用的是auth_user,我有一個基本的配置文件類。在我網站的每個頁面中,我使用一些用戶和配置文件數據,因此每個用戶查詢都應該加入配置文件。

我想在自定義管理器的get_query_set()方法中使用select_related,但我找不到任何合適的方法來定義一個或覆蓋現有的UserManager。有任何想法嗎?

注意:我不想覆蓋用戶模型。或者,更確切地說,我已經用不同的代理模型覆蓋了它。我希望在每個代理模型中都使用這個自定義管理器。

回答

6

好吧,終於找到了正確的答案。最簡潔的方法是使用自定義身份驗證後端。

# 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

這是相當醜陋的,但你可能monkeypatch用戶objects財產,例如。在中間件:

# 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 

然後在settings.py替換行:

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

通過:

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

注意1:這個代碼是純粹單位理論,從來沒有測試我也沒有時間。

注2:從長期可維護性的角度來看,我不推薦使用此解決方案。注3:如果有人提出其他建議,你應該比他更傾聽他或她的意見。注意4:作爲一個可能更好的主意,爲什麼不試圖查詢配置文件,這是一個您可以完全控制的模型類?你總是可以從配置文件檢索用戶對象,所以...

+0

因爲我找不到更清潔的方式,我會接受這個答案。但是,我在django BT中填寫了一個錯誤報告。等着瞧。 https://code.djangoproject.com/ticket/16379 –

+3

你應該真的不接受這個答案,因爲初學者可以得出這樣的結論:解決你提出的問題是一個可接受的方法,而不是。 – NiKo

+0

試過了,它沒有工作唉...對我來說是一個簡單的解決方法 – James