4

他の多くの人と同様に、ユーザー名フィールドとしてメールを使用するように Django アプリを構成しようとしています。カスタム ユーザー モデルに正常に移行した既存のユーザー アカウントがいくつかありますが、現在、カスタム モデルは Django ユーザー モデルと同じです。

# accounts/models.py

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
  pass

を に設定しようとするUSERNAME_FIELDemail、 を にUSERNAME_FIELD含めることができないというエラーREQUIRED_FIELDSと、一意でなければならないというエラーが表示されます。(補足: 基本ユーザーには電子メールは必要ないため、最初のエラーはわかりません)

AbstractUser のサブクラス化中にこの機能を取得する方法はありますか?

または、この例AbstractBaseUserのように、すべてのフィールドをサブクラス化して指定する必要がありますか?

後者の場合、Django User モデルとまったく同じフィールドを定義するにはどうすればよいでしょうか? 所有しているユーザーを失ったり、フィールドの不一致で問題が発生したりしたくありません。

ユーザー名として電子メール アドレスを使用するためだけに、カスタム モデルを完全に指定する必要があるのはばかげているように思われるので、ここで何かが欠けている可能性があります。Django User モデルで一意のフィールドを確保する方法があれば、これは問題にならないと思います。

4

1 に答える 1

4

Django docが言うように:

必要な変更が純粋に動作上のものであり、データベースに保存されているものを変更する必要がない場合は、ユーザーに基づいてプロキシ モデルを作成できます。

Userカスタムモデルに置き換えたいので:

たとえば、一部のサイトでは、ユーザー名の代わりに電子メール アドレスを ID トークンとして使用する方が理にかなっています。

Userをサブクラス化して、独自のモデルを実装する必要がありますAbstractBaseUser。以下は、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)
于 2016-02-20T19:52:14.980 に答える