ユーザ登録を行ったときにメールアドレスの検証を終えるまではログインできないようにしたい.ここではその前段階として,ユーザ登録してもログインができないように設定を変更します.
このためには,users_user
テーブルの is_active
属性を 0 にします.実装の方法はいくつか考えられますが,forms.py
の中で行うことにします.
users/forms.py
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
error_messages = {
"password_mismatch": _("The two password fields didn’t match."),
}
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(attrs={"autocomplete": "new-password", 'class': 'form-control'}),
help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(attrs={"autocomplete": "new-password", 'class': 'form-control'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
)
class Meta:
model = UserModel
fields = ("username", 'first_name', 'last_name', 'email')
field_classes = {"username": UsernameField}
widgets = {
'first_name': forms.TextInput(attrs={
'class': 'form-control',
'required' : True
}),
'last_name': forms.TextInput(attrs={
'class': 'form-control',
'required' : True
}),
'email': forms.EmailInput(attrs={
"autocomplete": "email",
'class': 'form-control',
'required' : True
}),
}
labels = {
'first_name': 'First Name',
'last_name': 'Last Name',
'email': 'Email',
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self._meta.model.USERNAME_FIELD in self.fields:
self.fields[self._meta.model.USERNAME_FIELD].widget.attrs[
"autofocus"
] = True
def clean(self):
data = super().clean()
first_name = data.get('first_name')
last_name = data.get('last_name')
if len(first_name) == 0:
msg = "First Name が入力されていません"
self.add_error('first_name', msg)
elif len(first_name) > 20:
msg = "First Name の最大文字数は20文字です"
self.add_error('first_name', msg)
if len(last_name) == 0:
msg = "Last Name が入力されていません"
self.add_error('last_name', msg)
elif len(last_name) > 20:
msg = "Last Name の最大文字数は20文字です"
self.add_error('last_name', msg)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise ValidationError(
self.error_messages["password_mismatch"],
code="password_mismatch",
)
return password2
def _post_clean(self):
super()._post_clean()
# Validate the password after self.instance is updated with form data
# by super().
password = self.cleaned_data.get("password2")
if password:
try:
password_validation.validate_password(password, self.instance)
except ValidationError as error:
self.add_error("password2", error)
def save(self, commit=True):
user = super().save(commit=False)
user.is_active = False # まだログインできないようにする
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
ユーザ登録後に表示されるフラッシュメッセージを変更しておきます.
users/views.py
class UserCreateView(CreateView):
template_name = 'users/create_form.html'
form_class = UserCreationForm
def form_valid(self, form):
messages.success(self.request, 'ユーザ登録しましたが,まだログインはできません')
user = form.save()
return HttpResponseRedirect("/")
新たにユーザ登録したユーザ ID ではログインできないことが確認できます.なお,ログインできない理由がパスワードが異なるからなのか,アカウントが有効化されていないからなのかが,現時点のエラーメッセージでは理解できません.このあたりはあとで修正しましょう.