(2019/1/25 ACCOUNT_USER_MODEL_USERNAME_FIELDについて追記)
環境
- Python 3.6.6
- Django 2.1.5
- django-allauth 0.38.0
エラー内容
DjangoのUserモデルについて、
- ユーザー名とパスワード
ではなく
- メールアドレスとパスワード
で認証するようにカスタマイズした上で、django-allauthを使用したところ、
- ログインページ(
accounts/login/
) - サインアップページ(
accounts/signup/
)
にアクセスしたら、以下のエラーになりました。
username
フィールドが無い、とのこと。
File "/Users/(略)/venv/lib/python3.6/site-packages/allauth/utils.py", line 68, in get_username_max_length
max_length = User._meta.get_field(USER_MODEL_USERNAME_FIELD).max_length
File "/Users/(略)/venv/lib/python3.6/site-packages/django/db/models/options.py", line 566, in get_field
raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: User has no field named 'username'
対処方法
settings.pyに以下を追加します。
settings.py
ACCOUNT_AUTHENTICATION_METHOD = 'email' # 認証方法をメールアドレスにする
ACCOUNT_USER_MODEL_USERNAME_FIELD = None # Userモデルにusernameは無い
ACCOUNT_EMAIL_REQUIRED = True # メールアドレスを要求する
ACCOUNT_USERNAME_REQUIRED = False # ユーザー名を要求しない
ログインページ(accounts/login/
)にアクセスすると無事に以下の画面が表示されるようになりました。
なお、ACCOUNT_USER_MODEL_USERNAME_FIELD = None
を設定しなくても、
- ログインページ(
accounts/login/
)へのアクセス - ログイン
- サインアップページ(
accounts/signup/
)へのアクセス
までは可能なのですが、実際にサインアップを行おうとするとNotImplementedError at /accounts/signup/
のエラーになってしまいます。
ですので、ACCOUNT_USER_MODEL_USERNAME_FIELD
についても設定してください。
補足情報:Userモデルのカスタマイズ内容
なお、補足情報としてUserモデルのカスタマイズ内容は以下の通りです。
users/models.py
from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.models import AbstractBaseUser
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
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()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
@property
def username(self):
return self.email