[Python Django] 2-3. FBV Form을이용한 Login, Logout 구현

2022. 3. 26. 09:29Python/Django Framework

반응형

Login 구현

1. form 등록

# user/forms.py

from django import forms
from django.contrib.auth.hashers import check_password
from django.forms.utils import ErrorList

from user.models import User


class LoginForm(forms.ModelForm):
    user_email = forms.EmailField(
        max_length=256,
        label="이메일",
        error_messages={"required": "이메일을 입력해주세요"}
    )
    password = forms.CharField(
        widget=forms.PasswordInput,
        min_length=8,
        max_length=16,
        label="비밀번호",
        error_messages={"required": "비밀번호를 입력해주세요"}
    )

    class Meta:
        model = User
        fields = ['user_email', 'password']

    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=None,
                 empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None):
        super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, field_order,
                         use_required_attribute, renderer)
        self.user_id = None

    def clean(self):
        clean_data = super().clean()
        user_email = clean_data.get('user_email')
        password = clean_data.get('password')

        if user_email and password:
            try:
                user = User.objects.get(user_email=user_email)
            except User.DoesNotExist:
                self.add_error('user_email', '존재하지 않는 이용자입니다')
                return

            if not check_password(password, user.password):
                self.add_error('password', '비밀번호를 확인해주세요')
            else:
                self.user_id = user.id

2. form을 통한 view 구현

# user/views.py

def login(request):
    if request.method == 'GET':
        form = LoginForm  # form을 가져온다
        return render(request, 'login.html', {'form': form})
    elif request.method == 'POST':
        form = LoginForm(request.POST)  # form에 POST 데이터를 전송하여 clean으로 무결성 검사
        if form.is_valid():  # 무결성 검사를 통과하면
            request.session['user_id'] = form.user_id  # user_id를 세션에 등록
            return redirect('/user/detail/')
        else:  # 에러 발생시 폼 다시 전달. filed.errors로 에러 메세지 출력
            return render(request, 'login.html', {'form': form})

3. 로그인 페이지 template 생성하여 form 정보를 통한 페이지 구현

# user/templates/login.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="mb-3">
                        <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 %}
                        <div style="color:red">{{ field.errors }}</div>
                    {% endif %}
                {% endfor %}
                <div class="d-grid mt-3">
                    <button class="btn btn-lg btn-primary" type="submit">회원수정</button>
                </div>
            </form>
        </div>
    </div>
{% endblock %}

Detail 페이지 구현

1. 로그인 후 이동할 detail 페이지 template 생성

  • 간단하게 user_name과 user_email만 출력하여 로그인 상태만 확인
# user/templates/detail.html

{% extends "base.html" %}
{% block contents %}
    <h1>{{ user.user_name }}</h1>
    <h2>{{ user.user_email }}</h2>
{% endblock %}

2. urls.py에 detail 페이지 연결

# user/urls.py

from django.urls import path

from user import views

urlpatterns = [
    path('detail/', views.detail),
    path('create/', views.create),
    path('login/', views.login)
]

3. view.py에서 session정보를 통해 user정보를 출력하는 view 설정 

# user/views.py

def detail(request):
    user_id = request.session.get('user_id')
    if user_id:
        user = User.objects.get(id=user_id)
        return render(request, 'detail.html', {'user': user})
    else:
        return redirect('/user/login/')

Logout 기능 구현

1. view.py에서 session정보를 삭제하는 logout기능 구현

# user/views.py

def logout(request):
    if request.session.get('user_id'):
        del request.session['user_id']
    return redirect("/user/login") # 로그아웃 후 로그인 페이지로 리다이렉트

2. urls.py에서 logout  페이지 연결

# user/urls.py

urlpatterns = [
    path('detail/', views.detail),
    path('create/', views.create),
    path('login/', views.login),
    path('logout/', views.logout) # 로그아웃 기능 추가
]
반응형