Расширение модели User с помощью пользовательских полей в Django

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

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

408
задан Farinha 27 June 2019 в 12:03
поделиться

6 ответов

Наименее болезненный и действительно рекомендуемый Джанго способ сделать это - через свойство OneToOneField(User).

Расширение существующей модели пользователя

& hellip;

Если вы хотите сохранить информацию, связанную с User, вы можете использовать отношение один к одному к модели, содержащей поля для дополнительной информации. Эту модель «один к одному» часто называют моделью профиля, поскольку она может хранить информацию, не связанную с аутентификацией, о пользователе сайта.

Тем не менее, расширение django.contrib.auth.models.User и вытеснение его также работает ...

Подстановка пользовательской модели пользователя

Некоторые типы проектов могут иметь требования к аутентификации, для которых встроенная модель User Django не всегда подходит. Например, на некоторых сайтах имеет смысл использовать адрес электронной почты в качестве идентификационного токена вместо имени пользователя.

[Ред .: За следуют два предупреждения и уведомление, упоминая, что это довольно радикально .]

Я бы определенно держитесь подальше от изменения фактического класса User в исходном дереве Django и / или копирования и изменения модуля auth.

233
ответ дан Nick T 27 June 2019 в 12:03
поделиться

Ну, прошло некоторое время с 2008 года, и пришло время для нового ответа Начиная с Django 1.5 вы сможете создавать пользовательский класс User. На самом деле, в то время, когда я пишу это, оно уже объединено с мастером, так что вы можете попробовать его.

Есть некоторая информация об этом в документах или, если вы хотите углубиться в это, в этот коммит .

Все, что вам нужно сделать, это добавить AUTH_USER_MODEL к настройкам, указав путь к пользовательскому классу пользователя, который расширяет либо AbstractBaseUser (более настраиваемая версия), либо AbstractUser (более или менее старый пользовательский класс, который вы можете расширить).

Для людей, которым лень кликать, вот пример кода (взят из документов ):

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        u = self.create_user(username,
                        password=password,
                        date_of_birth=date_of_birth
                    )
        u.is_admin = True
        u.save(using=self._db)
        return u


class MyUser(AbstractBaseUser):
    email = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin
188
ответ дан Ondrej Slinták 27 June 2019 в 12:03
поделиться

Существует официальная рекомендация на хранящая дополнительная информация о пользователях . Книга Django также обсуждает эту проблему в разделе Профили .

42
ответ дан Török Gábor 27 June 2019 в 12:03
поделиться

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

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

Используя вышеупомянутый подход:

  1. Вы не должны использовать пользователя get_profile () .newattribute для доступа к дополнительной информации, связанной с пользователем
  2. можно просто непосредственно получить доступ к дополнительным новым атрибутам через user.newattribute
22
ответ дан 22 November 2019 в 23:28
поделиться

В настоящее время с Django 2.2, рекомендуемый путь при запуске нового проекта состоит в том, чтобы создать пользовательскую пользовательскую модель, которая наследовалась AbstractUser, затем укажите на AUTH_USER_MODEL на модель.

Источник: https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project

0
ответ дан 22 November 2019 в 23:28
поделиться

Примечание: этот ответ устарел. см. другие ответы, если вы используете Django 1.7 или новее.

Вот как я это делаю.

#in models.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):  
    user = models.OneToOneField(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):  
    if created:  
       profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

Это будет создавать профиль пользователя каждый раз при сохранении пользователя, если он создается. Затем вы можете использовать

  user.get_profile().whatever

Вот дополнительная информация из документации

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

Обновление : Обратите внимание, что AUTH_PROFILE_MODULE устарел, начиная с версии 1.5: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

223
ответ дан 22 November 2019 в 23:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: