Расширить модель Django User (сделать так, чтобы она работала в request.user), Django 1.2.3

Я хотел бы расширить модель User, чтобы я мог добавить некоторые дополнительные поля и функции (не только поля, имейте в виду, либо иначе (ну, все же), я мог бы использовать get_profile(), что я считаю уродливым).

Также я хотел бы использовать эту новую расширенную модель User в request.user, например:

Модель расширенного пользователя:

# imports etc

class CustomUser(User):
    extra_field = ...

    def extra_function(self):
        ...

        return ...

Пример использования вида:

# imports etc

def extra_function_view(request):
    print request.user.username
    print request.user.extra_field

    request.user.extra_function()

    return HttpResponse( ... )

Вышеприведенный код явно не работает, потому что extra_field и extra_function отсутствуют в модели User.

Теперь я нашел способ сделать это, используя аутентификационный бэкэнд, который довольно сложен и который я не смог заставить работать в Django 1.2.3.

AUTHENTICATION_BACKENDS = (
    'myproject.auth_backends.CustomUserModelBackend',
)
...

CUSTOM_USER_MODEL = 'accounts.CustomUser'

Дальше все больше пробовали некоторые другие методы, такие как использование сигналов, которые не работали. На мой взгляд, единственное решение, по-видимому, заключается в настройке модели User в Django (что не является элегантным решением, корректирующим исходный код Django, но является разумным решением с точки зрения кода).

Так что я ищу решение для этого.. кто-нибудь делал это раньше?

Спасибо сейчас

Стефан

1 ответ

Вы на правильном пути с настройкой Аутентификации Backend.

Бэкенды аутентификации могут быть довольно простыми, вот наш фрагмент, который мы используем в нашем проекте.

class LocalAccount(object):
    def authenticate(self, system=None, username=None, password=None):
        try:
            user = User.objects.get(system=system, alias=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        'returns user'

    def get_all_permissions(self, user_obj):
        'returns user permissions'

    def has_perm(self, user_obj, perm):
        'verifies permission, remember you can hardcode these'

    def get_group_permissions(self, user_obj):
        return set() #We don't use this

    def has_module_perms(self, user_obj, app_label):
        return False

Это позволяет вам возвращать любую пользовательскую модель, которую вы хотите вернуть. Пока ваша пользовательская модель в основном похожа на пользовательскую модель Django, у вас не возникнет никаких проблем.

Также имейте в виду, что расширение пользователя и включение приложения приведет к тому, что модель Django User и ваша собственная модель User будут находиться в базе данных с наследованием модели. Лучший вариант - скопировать модель пользователя Django и изменить ее. Для нашего проекта мы даже не включаем "auth" в настройку установленных приложений.

Идея здесь - типизация Python Duck. Поскольку созданная вами модель User имеет тот же интерфейс, который ищет Django (методы, поля), не имеет значения, действительно ли это класс User, который она указала.

Другие вопросы по тегам