Переопределить UserManager в Django - PullRequest
9 голосов
/ 29 июня 2011

Как я могу использовать собственный менеджер для класса auth_user в django?

В моем проекте django я использую auth_user, и у меня есть базовый класс профиля. На каждой странице моего сайта я использую некоторые данные пользователя и профиля, поэтому каждый пользовательский запрос должен присоединяться к профилю.

Я хотел использовать select_related в методе get_query_set() в пользовательском менеджере, но я не могу найти какой-либо правильный способ его определить или переопределить существующий UserManager. Есть идеи?

Примечание: я не хочу переопределять пользовательскую модель. Или, если быть более точным, я уже переопределил это в разных моделях прокси. Я хочу, чтобы этот пользовательский менеджер использовался в каждой модели прокси.

Ответы [ 2 ]

7 голосов
/ 13 июня 2013

Хорошо, наконец-то нашел правильный ответ.Самый простой способ - использовать пользовательский сервер аутентификации.

# 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 голосов
/ 29 июня 2011

Это довольно некрасиво, но вы, вероятно, можете обезопасить пользовательское свойство 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. Как, вероятно, лучшая идея, почему бы не попытаться запросить профиль, который является классом модели, над которым вы имеете полный контроль? Вы всегда можете извлечь пользовательский объект из профиля, так что…

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...