ここまでの作業の結果では,新規にユーザ登録をしてまだメールによるアカウント有効化を終えていないユーザがログインしようとしたときに,「ID とパスワードが異なります」というメッセージが表示されてしまいます.ここでは未検証ユーザのログインエラーメッセージを変更してみよう.
まず,ユーザ user_e の is_active を 0 に変更します.
sqlite> select id, username, is_active, email from users_user; ⏎ id|username|is_active|email 1|user_a|1|a@sample.com 2|user_b|1|b@sample.com 3|user_c|1|c@sample.com 4|root|1|root@example.com 7|user_e|1|e@sample.com sqlite> update users_user set is_active = 0 where id = 7; ⏎ sqlite> select id, username, is_active, email from users_user; ⏎ id|username|is_active|email 1|user_a|1|a@sample.com 2|user_b|1|b@sample.com 3|user_c|1|c@sample.com 4|root|1|root@example.com 7|user_e|0|e@sample.com sqlite>
アカウントが有効化された user_a のエラーメッセージです.
アカウントの検証を終えていないユーザ user_e でも同じエラーメッセージが表示され,これは不親切かもしれません.
エラーメッセージの処理は forms.py に記述します.
users/forms.py
class AuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
username = UsernameField(widget=forms.TextInput(attrs={"autofocus": True}))
password = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(attrs={"autocomplete": "current-password", 'class': 'form-control'}),
)
error_messages = {
"invalid_login": _(
"Please enter a correct %(username)s and password. Note that both "
"fields may be case-sensitive."
),
"inactive": _("This account is inactive."),
}
def __init__(self, request=None, *args, **kwargs):
"""
The 'request' parameter is set for custom auth use by subclasses.
The form data comes in via the standard 'data' kwarg.
"""
self.request = request
self.user_cache = None
super().__init__(*args, **kwargs)
# Set the max length and label for the "username" field.
self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
username_max_length = self.username_field.max_length or 254
self.fields["username"].max_length = username_max_length
self.fields["username"].widget.attrs["maxlength"] = username_max_length
if self.fields["username"].label is None:
self.fields["username"].label = capfirst(self.username_field.verbose_name)
def clean(self):
username = self.cleaned_data.get("username")
password = self.cleaned_data.get("password")
if username is not None and password:
# is_active が 0 のときに authenticate が None になってしまうため
inactive_user = UserModel.objects.filter(username=username)
if len(inactive_user) > 0:
if not inactive_user[0].is_active:
self.add_error('username', 'ログインする前にメールの検証を行ってアカウントを有効化してください.')
self.add_error('username', 'ユーザ登録後にメールが届いているはずです.アカウントを有効化するにはそのメールの指示に従ってください.')
self.add_error('username', '検証メールの有効期限が切れた場合はユーザ登録ページからメールを再送信してください.')
raise ValidationError(
self.error_messages["inactive"],
code="inactive",
)
self.user_cache = authenticate(
self.request, username=username, password=password
)
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
アカウントの検証を終えていないユーザ user_e のエラーメッセージが変更されました.