Кто-нибудь думает, что пользовательская модель django слишком тесно связана с аутентификацией? - PullRequest
4 голосов
/ 24 января 2010

Я пытаюсь выучить Django, и я хотел бы получить отзывы от любого, кто имеет опыт работы с MVC / MTV / PHP / Ruby Framework. Кто-нибудь находит, что пользовательская модель слишком тесно связана с аутентификацией?

Справочная информация: Когда вы впервые внедряете аутентификацию для Django, вы включаете модуль django.contrib.auth

Это приведет к появлению нескольких моделей, таких как «Пользователь», «Группа», «Сообщение» и т. Д. Давайте сосредоточимся на модели «Пользователь», так как это одна из самых важных таблиц на любом веб-сайте.

Короче говоря, в таблице User есть эти поля

Пользователь

  • имя пользователя max_length 30, уникальный, [буквы, цифры, подчеркивания]
  • пароль max_length 75
  • электронная почта max_length 75
  • ... и около 8 других полезных полей, таких как first_name, last_name и т. Д.

Цель:

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

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

Добавление новых полей в модель пользователя

Django docs говорит, что нужно использовать создать другую таблицу и вставить туда поля. Вы будете иметь отношение один к одному между таблицей User и таблицей Profile. например. Если вы хотите добавить поле изображения для каждого пользователя, вы добавляете его в таблицу профилей. Запрос на соединение выполняется каждый раз. Они даже указали константу, чтобы сообщить платформе, какую таблицу использовать: AUTH_PROFILE_MODULE = 'accounts.UserProfile' Я не думаю, что лучше делать запрос на соединение каждый раз, когда я хочу, чтобы поле принадлежало пользовательской таблице.

Другой вариант - использовать функцию add_to_class. Сообщество django заявило, что нецелесообразно определять новые поля вне основного класса, потому что другие разработчики, добавляющие методы, не будут знать всех членов данных.

Редактирование старых полей

Модуль проверки подлинности проверяет два поля: имя пользователя и хешированный пароль. Глядя на приведенную выше таблицу, мне нужно изменить модель имени пользователя, чтобы принять эти свойства. Длина 75 со всеми действительными символами электронной почты. Джанго предлагает мне проверить по полю электронной почты.

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

Добавление новых методов

В MVC / MTV принцип дизайна заключается в использовании толстых моделей тощих контроллеров. Поскольку модель объявлена ​​в auth, я не уверен, как можно добавлять методы, которые воздействуют на поля пользовательской модели. Поскольку django предлагает использовать модель профиля, я полагаю, что они должны будут пойти туда.

Расширение класса пользователя

Небольшое раздражение вызвало бы то, что я не могу использовать имя «Пользователь» и вместо этого должен использовать «Пользователи» или «Учетные записи». Более того, я не думаю, что автор распознал бы этот новый модуль. Это означает, что мне придется переписать кучу функциональных возможностей, которые присутствуют. Это меня не беспокоит, так как я ожидаю, что я это сделаю в других рамках.

Любые комментарии приветствуются. Я бы не задавал все эти вопросы и не искал бы решения, если бы не был действительно заинтересован в использовании django.

Ответы [ 3 ]

4 голосов
/ 13 февраля 2010

Я согласен, что непреклонная привязанность Джанго к аутентичным моделям абсурдна. Моя работа требует, чтобы я создавал ультрамасштабируемые и очень загруженные сайты, которые иногда требуют аутентификации пользователя, а авторизация djano модель + разрешения не подходят для этого.

К счастью, заменить несложно.

Сначала создайте пользовательскую модель пользователя.

class User(models.Model):
    ...fields...
    #Define some interface methods to be compatible.
    def get_and_delete_messages(self):
    def is_active(self):
    def is_anonymous(self):
    def is_authenticated(self):
    def is_staff(self):
    def has_perm(self, perm_list):

Во-вторых, создайте свой собственный сервер аутентификации.

class LocalAccount(object):
    """
    This checks our local user DB for authentication
    """
    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(alias=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.select_related().get(pk=user_id)
        except User.DoesNotExist:
            return None

#settings.py
AUTHENTICATION_BACKENDS = (
    'helpers.auth.LocalAccount',
)

Это должно решить большинство ваших проблем, я даже не думаю, что все методы, которые вы найдете на django.contrib.auth.User, необходимы, я рекомендую попробовать.

Единственное, что здесь нужно сделать, это то, что администратор может начать скулить, к счастью, это действительно легко исправить с помощью простого наследования Python. Это еще один вопрос:)

1 голос
/ 24 января 2010

В конце дня бэкэнд аутентификации вашего проекта нуждается в каком-то хранилище для аутентификационных учетных данных. То, что бэкэнд аутентификации по умолчанию тесно связан с моделью User, не является странным в этом отношении. Достаточно просто заменить ваше собственное определение для пользовательской модели, если вы напишите свой собственный аутентификационный бэкэнд, как У меня в прошлом .

0 голосов
/ 07 февраля 2010

Я создал свою модель профиля и использую AUTH_PROFILE_MODULE, поэтому у меня есть полный контроль над моей моделью, я могу изменять поля, добавлять методы и т. Д. Теперь я думаю об использовании кэша и написании промежуточного программного обеспечения, которое по возможности получит профиль из кэша .

Для входа по электронной почте вы можете написать очень простой аутентификационный бэкэнд:

from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend

class EmailModelBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...