이전에는 PasswordResetView / PasswordResetDoneView / PasswordResetConfirmView / PasswordResetCompleteView 를 통해 간단하게 구현해냈다. 그렇다면 이번에는 만약 아이디를 까먹었을 때, 이메일로 아이디를 보내주는 것을 한번 구현해보도록 하겠다.
※ forgot_id.html 만들기 / urls.py 추가하기
우선, 로그인이 되어있지 않을때, 아이디를 까먹었다는 링크를 누르게 된면 해당 페이지로 이동하게끔 해줄 것이다.
Forgot ID?를 누른다면 다음과 같은 HTML 템플릿으로 이동한다.
<h3>Forgot ID</h3>
<p>Forgotten your ID? Enter your email address below, and we’ll email your ID.</p>
<form method="post">
{% csrf_token %}
Email: <input type="email" name="email">
<input type="Submit" name="email_submit">
{% for message in messages %}
{{message}}
{% endfor %}
</form>
여기에는 email을 넣을 수 있는 박스가 존재하고, input type="email로 해주어야 이메일을 받아들이는지 Django가 인식 할 수 있을 것이다. 아래의 message는 조금 있다가 설명하도록 하겠다.
다음은 urls.py에 다음과 같은 path를 추가해준다;
from django.urls import path
from . import views
urlpatterns = [
...
path('forgot_id/', views.ForgotIDView, name="forgot_id"),
...
]
※ views.py 수정하기
이제는 ForgotIDView를 추가하여, 들어오려는 사용자가 form이 있는 이 페이지에 접근 했을 때, 그리고 이 페이지에서 데이터를 통과시킬 때 어떤 행동을 취해줄 것인지 views.py에 쓴다.
# views.py
from django.shortcuts import render, redirect
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.models import User
from django.core.mail import EmailMessage
from .decorators import unauthenticated_user
@unauthenticated_user
def ForgotIDView(request):
context = {}
if request.method == 'POST':
email = request.POST.get('email')
try:
user = User.objects.get(email=email)
if user is not None:
method_email = EmailMessage(
'Your ID is in the email',
str(user.username),
settings.EMAIL_HOST_USER,
[email],
)
method_email.send(fail_silently=False)
return render(request, 'accounts/id_sent.html', context)
except:
messages.info(request, "There is no username along with the email")
context = {}
return render(request, 'accounts/forgot_id.html', context)
- 우선 함수가 request.method가 POST인지 확인을 한다.
- 그리고 이 email이라는 변수에 request.POST.get('email')을 저장시켜준다.
- try라는 method를 통해 user라는 변수값에 User.objects.get(email=email)을 통해 POST된 email값을 가진 사용자를 불러온다.
- 만약 그러한 사용자가 없으면 except에 선언된 messages.info를 통해 해당 이메일을 가진 사용자는 없다는 것을 메세지로 출력해준다.
- 해당 이메일을 가진 사용자가 있을 경우, method_email에 EmailMessage를 저장시켜주는데, 이때 괄호 안에 있는 값들을 통과시킨다 (이 부분에 대해서는 밑에 설명하겠다.)
- 이후, 성공적으로 이메일이 보내졌으면, id_sent.html로 이동시킨다.
EmailMessage란 무엇인가?
우선 이 EmailMessage를 설명하기 위해서는 Sending Email이라는 Django Documentation을 봐야한다:
- subject - 'Hello' 인 부분은 이메일의 제목이라고 생각하면 된다
- body - 'Body goes here' 인 부분은 메일의 내용이라고 생각하면 된다. 이를 render_to_string을 사용하여 html template을 로딩하는 방법이 있다.
- from_email - 'from@example.com'인 부분은 보내는 사람의 이메일이다. 우리는 settings를 import하여 settings.EMAIL_HOST_USER을 사용하여 settings.py에 써놓은 이메일을 불러와준다.
- to - ['to1@example.com', 'to2@example.com']은 보내는 대상의 이메일들을 리스트로 넣는 것이다. 이번 포스팅의 경우 입력받은 이메일을 통과시켜주는 것이기 때문에 우리는 [email]로 대체하였다.
- bcc - ['bcc@example.com']은 숨은 참조인데, 거의 사용할 일이 없으리라 생각된다.
마지막으로 method_email.send(fail_silently=False)를 통해, 이메일 보내면서 생기는 예외들은 무시처리 시켜주면서 이메일을 송신시켜주는 역할을 한다.
Email Template을 추가하기
아까 말한, views.py의 body에 render_to_string을 사용하여 html template을 추가할 수 있다고 말했다. 이는 다음과 같이 views.py를 수정해주면 된다:
# views.py
...
from django.template.loader import render_to_string
...
def ForgotIDView(request):
context = {}
if request.method == 'POST':
email = request.POST.get('email')
try:
user = User.objects.get(email=email)
if user is not None:
template = render_to_string('accounts/email_template.html', {'name': user.first_name, 'id':user.username})
method_email = EmailMessage(
'Your ID is in the email',
template,
settings.EMAIL_HOST_USER,
[email],
)
method_email.send(fail_silently=False)
return render(request, 'accounts/id_sent.html', context)
except:
messages.info(request, "There is no username along with the email")
render_to_string을 사용하여 accounts/email_template에 추가한 email_template.html을 통과시켜주고, 이 email_template 안에 있는 {{name}} 과 {{id}} 가 각각 무엇을 지칭할 것인지 나타내주게끔 하면된다.
email_template.html은 다음과 비슷하게 생겼을 것이다 (매우 간략한 버젼이다):
hey {{name}}!
The following is your ID:
{{id}}
※ urls.py 에 id_sent.html을 추가하지 않았는데 어떻게 작동하는 것일까
지금 보면 위의 urls.py에 id_sent.html에 관한 path를 추가하지 않았다. 그럼에도 불구하고 templates/accounts 폴더에 id_sent.html을 넣고, 이를 ForgotIDView에서 이메일을 보내고 return render 할 때 사용하는 것이 가능하다.
이유는 우리는 따로 이 id_sent.html을 접근하려고 할 것이 아니라, 단순히 이메일이 보내졌을 때만 접근하려고 하기 때문에 일반 사용자들이 접근을 하게끔 할 필요도 없을 뿐더러, 없어도 잘 작동하기 때문이다. 따라서 다로 주소창에 localhost:8000/id_sent/ 와 같이 입력한다면 오류가 날 것이다.
이렇게 아이디를 까먹었을 때, 사용자의 이메일에 메일을 보내는 방식으로 아이디를 확인하는 방법에 대해 알아보았다.
'Django 공부하기' 카테고리의 다른 글
<Django 공부하기> Customizing Admin Page (1) - Customizing Users Page (0) | 2020.11.13 |
---|---|
<Django 공부하기> 회원탈퇴 구현하기 (1) - 단순 회원탈퇴 (No Password Needed) (0) | 2020.11.12 |
<Django 공부하기> forms.py란 무엇인가?? Form이란 무엇인가? (0) | 2020.11.09 |
<Django 공부하기> virtualenv를 통해 Django를 사용하기 (0) | 2020.11.09 |
<Django 공부하기> null=True와 blank=True의 차이점은?? (0) | 2020.11.07 |