코딩공부/Python Django

django password reset (2) - class PasswordReset Overriding

integerJI 2020. 8. 22. 23:48

들어가기에 앞서

 

Overriding를 위한 python views 확인 하기

 

django를 사용하다 보면 모든 파이썬 파일에서 django.~ 를 import 해주고 있다.

 

이 파일들은 무엇일까?

 

그리고 이 파일을 찾아서 확인해 보는 걸로 무엇을 할 수 있을까

 

가상 환경의 python3 확인

/Users/사용자이름/Desktop/project/자신의프로젝트/자신의가상환경/lib/python3.8/site-packages/django/contrib/auth

mac의 경우 가상 환경을 새로 설치한 경로를 따라가 보면 (저 같은 경우 myvenv)

 

myvenv/lib/python3.8/site-packages/가 있다.

 

이제 이곳에 있는 django 폴더에서 import를 해주어 django에서 제공하는 class를 사용할 수 있게 되는 것이다.

 

PasswordReset class 확인

 

위의 경로에서 django/contrdjango/contrib/auth/views.py를 실행한다.

 

내용을 보면 PasswordRest에 관련된 함수들이 있다.

 

PasswordResetView 상속

views.py

from django.contrib.auth.views import LoginView, LogoutView, PasswordResetView, PasswordResetDoneView
from django.contrib.auth.forms import (
    AuthenticationForm, PasswordChangeForm, PasswordResetForm, SetPasswordForm,
)

class UserPasswordResetView(PasswordResetView):
    template_name = 'password_reset.html' #템플릿을 변경하려면 이와같은 형식으로 입력
    success_url = reverse_lazy('password_reset_done')
    form_class = PasswordResetForm
    
    def form_valid(self, form):
        if User.objects.filter(email=self.request.POST.get("email")).exists():
            return super().form_valid(form)
        else:
            return render(self.request, 'password_reset_done_fail.html')
            
class UserPasswordResetDoneView(PasswordResetDoneView):
    template_name = 'password_reset_done.html' #템플릿을 변경하려면 이와같은 형식으로 입력

 

UserPasswordResetView를 만들어 PasswordResetView를 오버 라이딩해줍니다.

 

해당 내용은 django.contrib.auth.views.PasswordResetView 안에 있는 PasswordResetView 클래스의 소스를 가져온 것이며

 

UserPasswordResetView로 다시 정의해주었습니다.

 

이렇게 될 경우 django에서 제공하는 페이지가 아닌

 

직접 만든 페이지로 경로를 설정할 수 있습니다.

 

template_name : 자신의 password_reset.html로 이동

 

success_url : 성공 시 호출할reverse_lazy = password_reset_done

 

form_class : form을 불러와 넣어준다. import 해준 form 중 PasswordResetForm

 

그러기 위하여 

 

UserPasswordResetDoneView를 생성하여 주었습니다.

 

해당 class가 호출되면

 

template_name로 인하여 password_reset_done.html로 이동합니다.

 

다시 UserPasswordResetView로 돌아와서

 

기존 기능의 문제점인 존재하지 않는 이메일에 메일 발송 시 예외처리가 안되어있는 부분을

 

if User.objects.filter(email=self.request.POST.get("email")).exists():

 

를 설정하여 처리하여 줍니다.

 

만약 메일이 존재하지 않는다면

 

else:

    return render(self.request, 'password_reset_done_fail.html')

 

으로 넘어가 password_reset_done_fail.html를 호출합니다.

 

password_reset.html

<form method="post" action="{% url 'password_reset' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">회원가입</button>
</form>

 

views에서 정의해준 form을 가져옵니다.

 

password_reset_done.html

 

메일 보내기 성공 페이지는 천천히 수정합니다.

 

password_reset_done_fail.html

 

urls.py

    path('password_reset/', views.UserPasswordResetView.as_view(), name="password_reset"),
    path('password_reset_done/', views.UserPasswordResetDoneView.as_view(), name="password_reset_done"),

 

urls.py에서는 저희가 새로 만든 class를 호출하여 줍니다.

 

기존의 소스

path('password_reset/', auth_views.PasswordResetView.as_view(), name="password_reset"),

path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(), name="password_reset_done"),

 

-->>

 

path('password_reset/', views.UserPasswordResetView.as_view(), name="password_reset"),

path('password_reset_done/', views.UserPasswordResetDoneView.as_view(), name="password_reset_done"),

 

auth_views에서 호출하는 방식을

 

자신의 app에 있는 views에 새롭게 선언한 UserPasswordReset~를 호출합니다.

 

확인하기

짜잔 password_reset 페이지가 새롭게 바뀌었습니다.

 

이제 저번 게시글에서의 문제점

 

존재하지 않는 이메일을 입력 후 발송을 눌러보면

 

 

정상적으로 예외처리가 되고 있으며

 

회원의 이메일을 전송하면

 

 

성공 페이지로 잘 넘어갔습니다.

 

메일을 확인해 보니 잘 왔고 다음 게시물에서 나머지 페이지를 마무리하겠습니다.


처음 이 기능을 보며 오버 라이딩? 저게 뭐지? 했었던 기능들을

 

알고 보니 저도 많이 사용하고 있었더군요

 

그때는 오버 라이딩이 뭔지, 어떤 파일을 가지고 오는지 모르고 썼다면

 

이제는 가상 환경에 있는 python은 무엇이며 

 

django에 있는 파일들을 어떻게 활용하는지 알 수 있었던 좋은 기회였습니다.