장고(Django) 핥짝 맛보기 - 이메일 인증을 참고
django.core.mail
인증 이메일 재발송
- 이메일 발송 부분은 분리했으니 재발송 view만 작성해준다.
# user/views.py
from django.views.generic import CreateView, FormView
from user.forms import UserRegisterForm, VerificationEmailForm
# 인증 이메일 재발송
class ResendVerifyEmail(VerifyEmailMixin, FormView):
model = get_user_model()
form_class = VerificationEmailForm
template_name = 'user/resend_verify_email.html'
success_url = '/user/login/'
def form_valid(self, form):
email = form.cleaned_data['email']
try:
user = self.model.objects.get(email=email)
except self.model.DoesNotExist:
messages.error(self.request, '알 수 없는 사용자 입니다.')
else:
self.send_verification_email(user)
return super().form_valid(form)
- from_class에
VerificationEmailForm
폼 클래스를 지정한다. - ModelForm을 지정한 회원가입 view와 달리 VerificationEmailForm은 From을 상속한 클래스로 구현한다. DB에 저장할 것도 없고 success_url로 이동시키는 역할만 하기 위해서 이다.
- 폼 클래스는 유효성 검증이 끝나면
cleaned_data
변수에 각 필드 이름으로 사용자가 입력한 값을 저장한다. - 이메일이 확인되면 인증 이메일을 발송하는 메소드를 호출한다.
# user/forms.py
from django import forms
from . validators import RegisteredEmailValidator
class VerificationEmailForm(forms.Form):
email = forms.EmailField(
widget=forms.EmailInput(attrs={'autofocus': True}),
validators=(forms.EmailField.default_validators + [RegisteredEmailValidator()])
)
- 이메일 하나만 입력 받고, 유효성 검증 필터를 default_validators에 추가하기 위해
RegisteredEmailValidator
인스턴스를 사용한다. - 에러 메시지를 필드에 표시하기 위해 view가 아니라 필드에 유효성을 검증한다.
# user/validators.py
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
class RegisteredEmailValidator:
user_model = get_user_model()
code = 'invalid'
def __call__(self, email):
try:
user = self.user_model.objects.get(email=email)
except self.user_model.DoesNotExist:
raise ValidationError('가입되지 않은 이메일입니다.', code=self.code)
else:
if user.is_active:
raise ValidationError('이미 인증되어 있습니다.', code=self.code)
return
RegisteredEmailValidator
는 이미 인증된 이메일인지, 가입된 적이 없는 이메일인지 검사하는 유효성 검증 필터로 구현한다.- 필드의 유효성 검증 필터는 반드시 call 메소드를 오버라이딩해야 한다.
- 폼의 필드는 유효성을 검증할 때 필드에 정의된 필터 리스트(
default_validators
)의 각 원소들이 호출되어 필드 값을 전달하여 검증한다.
# user/urls.py
app_name = 'user'
urlpatterns = [
path('resend_verify_email/', views.ResendVerifyEmail.as_view(), name="resend")
]
- 인증 이메일 재발송 view를 url에 등록한다.