2016-02-20 4 views
2

Как и многие другие, я пытаюсь настроить приложение Django для использования электронной почты в качестве поля имени пользователя. У меня есть некоторые существующие учетные записи пользователей, которые я мигрировали к пользовательской модели пользователя успешно, хотя сейчас обычай модель идентична модели пользователя Django:Django: расширяет приложение AbstractBaseUser, чтобы использовать электронную почту как USERNAME_FIELD?

# accounts/models.py 

from django.contrib.auth.models import AbstractUser 

class User(AbstractUser): 
    pass 

В любое время я пытаюсь установить USERNAME_FIELD в email, я получаю что USERNAME_FIELD не может быть включен в REQUIRED_FIELDS, а также ошибка, которая должна быть уникальной. (примечание стороны: электронная почта не требуется для пользователя базы, поэтому я не понимаю первую ошибку)

Есть ли способ получить эту функциональность при подклассификации AbstractUser?

Или мне просто нужно подкласса AbstractBaseUser и указать все поля, в порядке example?

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

Кажется глупым, чтобы пройти весь путь до полного указания пользовательской модели, чтобы использовать адрес электронной почты в качестве имени пользователя, поэтому, возможно, я что-то пропустил. Если бы был способ обеспечить уникальные поля в модели Django User, я не думаю, что это будет проблемой.

ответ

1

Как Django doc говорит:

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

Так как вы хотите, чтобы заменить его с пользовательской User модели:

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

Вам нужно реализовать свою собственную User модель, подклассов AbstractBaseUser. Вот пример кода с Джанго premissions включены также:

class User(AbstractBaseUser, PermissionsMixin): 
    """ 
    A class implementing a fully featured User model with admin-compliant 
    permissions. 

    Email and password are required. Other fields are optional. 
    """ 

    email = models.EmailField(
     _('Email Address'), unique=True, 
     error_messages={ 
      'unique': _("A user with that email already exists."), 
     } 
    ) 
    username = models.CharField(
     _('Username'), max_length=30, unique=True, blank=True, null=True, 
     help_text=_('30 characters or fewer. Letters, digits and _ only.'), 
     validators=[ 
      validators.RegexValidator(
       r'^\w+$', 
       _('Enter a valid username. This value may contain only ' 
        'letters, numbers and _ character.'), 
       'invalid' 
      ), 
     ], 
     error_messages={ 
      'unique': _("The username is already taken."), 
     } 
    ) 
    is_staff = models.BooleanField(
     _('Staff Status'), default=False, 
     help_text=_('Designates whether the user can log into this admin ' 
        'site.') 
    ) 
    is_active = models.BooleanField(
     _('Active'), default=True, 
     help_text=_('Designates whether this user should be treated as ' 
        'active. Unselect this instead of deleting accounts.') 
    ) 
    date_joined = models.DateTimeField(_('Date Joined'), default=timezone.now) 

    objects = UserManager() 

    USERNAME_FIELD = 'email' 

    class Meta(object): 
     verbose_name = _('User') 
     verbose_name_plural = _('Users') 
     abstract = False 

    def get_full_name(self): 
     """ 
     Returns email instead of the fullname for the user. 
     """ 
     return email_to_name(self.email) 

    def get_short_name(self): 
     """ 
     Returns the short name for the user. 
     This function works the same as `get_full_name` method. 
     It's just included for django built-in user comparability. 
     """ 
     return self.get_full_name() 

    def __str__(self): 
     return self.email 

    def email_user(self, subject, message, from_email=None, **kwargs): 
     """ 
     Sends an email to this User. 
     """ 
     send_mail(subject, message, from_email, [self.email], **kwargs) 
+0

так Благодарения и так как у меня существующих пользователей, мне нужно точно воссоздать существующую модель 'User' путем расширения' AbstractBaseUser'? Наверное, я немного обеспокоен копированием в той же проблеме, что и в источнике (так много для DRY) и имеет проблемы с конфликтом. – dkhaupt

+0

Это закончилось тем, что мне пришлось удалить «abstract = True» из 'Meta' скопированное определение AbstractUser, но после этого все было в порядке. Благодаря! – dkhaupt

+0

Добро пожаловать. Я использовал 'abstract = False' в моем коде. Использование одного и того же имени класса не вызовет никаких проблем, если вы будете осторожны при импорте класса 'User'. – Saeed

Смежные вопросы