2011-06-29 63 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