로그인 기능 구현을 위한 클래스 뷰를 만들어 볼게요.
form_valid()메서드를 통하여 session이 생성되었어요. 로그인 이후 redirect되게됩니다.
그때 index(request)메소드의 3번째 메소드에서 session값이 넘어가요.
user/views.py
from django.shortcuts import render
from django.views.generic.edit import FormView # form을 활용할수 있게 해주는 클래스에요
from user.forms import RegisterForm, LoginForm # forms.py에서 만든 클래스 임포트함.
def index(request):
return render(request,'index.html',{'email':request.session.get('user')}) # 3번째 인자는 session안의 user를 가져오도록 했어요.
class RegisterView(FormView):
template_name = 'register.html' # template_name이라고 하면 html파일이조? 이게 부모인 FormView에서 가져온거에요.
form_class = RegisterForm # 위의 임포트든 된것을 form_class의 값으로 할당해줌.
success_url = '/' # 회원가입이 정상적으로 된 경우 해당 url로 화면 전환이 이루어짐
class LoginView(FormView):
template_name = 'login.html' # template_name이라고 하면 html파일이조? 이게 부모인 FormView에서 가져온거에요.
form_class = LoginForm
success_url = '/'
# LoginView.as_view()가 실행될 때
def form_valid(self, form): # form유효성(데이터가 정상일때)을 마쳤을 때 사용해요. 로그인이 정상적으로 되었는 경우!
self.request.session['user'] = form.email # sessuib에 키값 user를 생성하는데요. 그 값은 form의 email속성에서 가져다와요.
return super().form_valid(form) # 부모클래스 FormView에 있는 form_valid()메소드를 호출합니다.
클래스뷰를 만들었으면 클래스뷰가 당겨올 form이 있어야해요. 로그인폼을 만들어야 된다는 말이에요.
from django import forms
from django.contrib.auth.hashers import check_password, make_password # 비밀번호 저장시 make_password이용(hash값)
from user.models import User
class RegisterForm(forms.Form): # forms.Form을 상속받아요.
...
...
...
if password and re_password:
if password != re_password:
self.add_error('password', '비밀번호가 서로 다릅니다.')
self.add_error('re_password', '비밀번호가 서로 다릅니다.')
else:
user = User(
email = email,
password=make_password(password), # make_password()를 이용해 해쉬값으로 저장함
)
user.save() # db저장
class LoginForm(forms.Form):
email = forms.EmailField(
error_messages={
'required': '이메일을 입력해주세요'
},
max_length=64,
label='이메일',
)
password = forms.CharField(
error_messages={
'required':'비밀번호를 입력하세요'
},
widget=forms.PasswordInput,
label='비밀번호'
)
def clean(self): # validation을 진행하는 메서드
cleaned_data = super().clean() # 부모 클래스에서 갖고 있던 clean을 상속 받아요.
email = cleaned_data.get('email')
password = cleaned_data.get('password')
if password and email: # 비밀번호 입력란 2개가 입력되어야하고
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
self.add_error('email','해당 이메일이 없습니다.')
return
if not check_password(password, user.password): # 좌항은 사용자 입력값, 우항은 db에 있는값(hash값으로 저장된 비밀번호) 둘을 서로 비교해줘요.
self.add_error('password', '비밀번호가 틀렸습니다.')
else:
self.email = user.email # db에서 가져온 email 정보를 self.email에 할당할게요.
먼저 템플릿부터 만들게요.
보다시피 form기반으로 작성된 html 소스코드에요.
{% extends "base.html" %}
{% block contents %}
<div class="row mt-5">
<div class="col-12 text-center">
<h1>로그인</h1>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
{{ error }}
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<form method="POST" action=".">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
<input type="{{ field.field.widget.input_type }}" class="form-control" id="{{ field.id_for_label }}"
placeholder="{{ field.label }}" name="{{ field.name }}" />
</div>
{% if field.errors %}
<span style="color: red">{{ field.errors }}</span>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary">로그인</button>
</form>
</div>
</div>
{% endblock %}
from django.contrib import admin
from django.urls import path, include
from user.views import index, RegisterView, LoginView # 회원가입하기 위해 view갖고옴
from product.views import ProductList
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
path('register/', RegisterView.as_view()),
path('login/', LoginView.as_view()),
path('product/', ProductList.as_view())
]