[django] 초간단 쇼핑몰 - login, session

Hyeseong·2020년 12월 8일
0

project

목록 보기
2/3
post-thumbnail

로그인 만들기

view 작성

로그인 기능 구현을 위한 클래스 뷰를 만들어 볼게요.

key point - session 구현

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()메소드를 호출합니다.

LoginForm

클래스뷰를 만들었으면 클래스뷰가 당겨올 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에 할당할게요.

login.html 템플릿 작성

먼저 템플릿부터 만들게요.
보다시피 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 %}

url작성

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())

]
 

session 전달 완료

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글