繁体   English   中英

Django:是否需要扩展AbstractBaseUser才能将电子邮件用作USERNAME_FIELD?

[英]Django: is extending AbstractBaseUser required to use email as USERNAME_FIELD?

像许多其他应用程序一样,我正在尝试将Django应用程序配置为使用电子邮件作为用户名字段。 我有一些现有的用户帐户,可以成功迁移到自定义用户模型,尽管现在自定义模型与Django用户模型相同:

# accounts/models.py

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
  pass

每当我尝试将USERNAME_FIELD设置为email ,都会收到错误消息: USERNAME_FIELD无法包含在REQUIRED_FIELDS ,并且该错误必须唯一。 (旁注:基本用户不需要电子邮件,因此我不明白第一个错误)

在子类化AbstractUser时,有什么方法可以获取此功能?

还是只需要以本示例的方式子类AbstractBaseUser并指定每个字段?

如果是后者,我将如何确保定义与Django User模型完全相同的字段? 我不想失去自己的用户,也不想因为字段不匹配而引起问题。

仅使用电子邮件地址作为用户名就必须完全指定自定义模型是一件很愚蠢的事情,所以也许我在这里遗漏了一些东西。 如果有一种方法可以确保Django User模型中的唯一字段,那么我认为这不是问题。

正如Django文档所说:

如果您所需的更改纯粹是行为上的,并且不需要对数据库中存储的内容进行任何更改,则可以基于用户创建代理模型。

由于要用自定义User模型代替它,因此:

例如,在某些站点上,使用电子邮件地址代替您的用户名作为您的识别令牌更有意义。

您需要通过继承AbstractBaseUser来实现自己的User模型。 这是一个包含django权限的示例代码:

    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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM