2011-06-29 16 views
9

djangoのauth_userクラスのカスタムマネージャを使用するにはどうすればよいですか?djangoのUserManagerをオーバーライドします

私のdjangoプロジェクトでは、auth_userを使用しています。基本的なプロファイルクラスがあります。私のサイトのすべてのページで、私はいくつかのユーザーとプロファイルのデータを使用するので、すべてのユーザーのクエリはプロファイルに参加する必要があります。

カスタムマネージャのget_query_set()メソッドでselect_relatedを使用したかったが、定義する方法が見つからず、既存のUserManagerを上書きすることができませんでした。何か案は?

注:私はユーザーモデルを無効にしたくありません。あるいは、もっと正確に言えば、私は既に別のプロキシモデルでそれを打ち破っています。このカスタムマネージャをすべてのプロキシモデルで使用したいと思っています。

答えて

6

[OK]をクリックすると、正解が見つかりました。最もきれいな方法は、カスタム認証バックエンドを使用することです。

# 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

これはかなり醜いですが、おそらくユーザobjectsのプロパティをmonkeypatchすることができます。

# 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:このコードは、テストされたことがない、純粋にtheoricです私は時間がありません。

注2:このソリューションを長期的な保守性の観点から使用することはお勧めできませんでした。

注3:誰かが何か他のことを示唆している場合は、おそらく私以上の人のことを聞いてください。

注4:おそらくもっと良い考えとして、プロファイルを照会しようとしないでください。これは、完全にコントロールしているモデルクラスですか?とにかくプロファイルからユーザーオブジェクトをいつでも取得できます。

+0

私は清潔な方法を見つけることができないので、私はこの答えを受け入れるつもりです。しかし、私はdjango BTのバグレポートを埋めました。成り行きを見守る。 https://code.djangoproject.com/ticket/16379 –

+3

初心者は、あなたが問題を解決するための受け入れ可能なアプローチだと結論づけることができるので、本当にこの答えを受け入れるべきではありません。 – NiKo

+0

試してみましたが、うまくいきませんでした...簡単な回避策でしたか – James

関連する問題