Переопределить UserManager в django
как я могу использовать пользовательский менеджер для auth_user
класс в Джанго?
в моем проекте django я использую auth_user
и у меня есть базовый класс профиль. На каждой странице моего сайта, я использую некоторые данные пользователя и профиля, поэтому каждый запрос пользователя должен присоединиться профиля.
Я хотел использовать select_related
на get_query_set()
метод в пользовательском менеджере, но я не могу найти правильного способа определить его или переопределить существующий UserManager
. Есть идеи?
примечание: Я не хочу переопределите модель пользователя. Или, если быть более точным, я уже преодолел его в разных прокси-моделях. Я хочу, чтобы этот пользовательский менеджер использовался в каждой прокси-модели.
2 ответов
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
это довольно уродливо, но вы, вероятно, можете 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',
# ...
)
By:
# settings.py
MIDDLEWARE_CLASSES = (
# ...
'yourapp.middleware.MyAuthMiddleware',
# ...
)
Note1: этот код чисто теоретический, никогда не проверялся, и у меня нет времени.
Note2: я не мог бы рекомендовать использовать это решение с точки зрения долгосрочной ремонтопригодности.
Note3: если кто-то предложит что-то еще, вы наверное, стоит слушать его или ее больше, чем меня.
Note4: как, вероятно, лучшая идея, почему бы не попытаться запросить профиль, который является классом модели, который вы полностью контролируете? Вы всегда можете получить объект пользователя из профиля, так что...