장고에서는 로그인, 로그아웃 등과 같은 로직에 대한 기능들이 이미 settings.py에 앱으로 등록되어 있어 이것을 활용하면 간편하게 로그인, 로그아웃, 회원가입까지 구현할 수 있다.

# Application definition

INSTALLED_APPS = [
    'django.contrib.auth',
]

로그인, 로그아웃과 같은 기능들은 하나의 프로젝트 안에서 다른 앱들도 공용으로 사용될 여지가 충분하기 때문에 하나의 앱안에 기능을 구현하는 것은 부적절하다. 그렇기 때문에 common과 같은 앱을 따로 생성하여 다른 앱들과 공용으로 사용할 수 있게 구성한다.

 

1. common 앱 생성

django-admin startapp common

 

2. settings.py에 생성한 앱 등록

INSTALLED_APPS = [
    #생략
    'common.apps.CommonConfig',

]

3. project/urs.py 경로 추가

urlpatterns = [
   #생략
    path('common/',include('common.urls'))
]

 

3. common/urls.py

from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
app_name = 'common'

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='common/login.html'),name='login'),
    path('logout/', auth_views.LogoutView.as_view(),name='logout'),
    path('signup/', views.signup, name='signup'),
]

4. common/forms.py 회원가입 폼 만들기

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


class UserForm(UserCreationForm):
    email = forms.EmailField(label="이메일")

    class Meta:
        model = User
        fields = ("username", "email")

 

 

5..common/views.py

from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect

# Create your views here.

# 계정생성
from common.forms import UserForm


def signup(request):
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password = raw_password)
            login(request,user)
            return redirect('index')
    else:
        form = UserForm()
    return render(request, 'common/signup.html', {'form': form})

 

6. 템플릿 파일 생성

 

# common/login.html

{% extends "base.html" %}
{% block content %}
<div class="container my-3">
<!-- ------------------------------- 로그인 타이틀 , 회원가입 버튼 -------------------------------- -->
    <div class="row">
        <div class="col-4">
            <h4>로그인</h4>
        </div>
        <div class="col-8 text-right">
            <span>또는 <a href="{% url 'common:signup' %}">계정을 만드세요.</a></span>
        </div>
    </div>
<!-- ----------------------------------------------------------------------- -->
    <form method="post" class="post-form" action="{% url 'common:login' %}">
        {% csrf_token %}
        {% include "common/form_errors.html" %}
        <div class="form-group">
            <label for="username">사용자ID</label>
            <input type="text" class="form-control" name="username" id="username"
                   value="{{ form.username.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="password">비밀번호</label>
            <input type="password" class="form-control" name="password" id="password"
                   value="{{ form.password.value|default_if_none:'' }}">
        </div>
        <button type="submit" class="btn btn-primary">로그인</button>
    </form>
</div>
{% endblock %}

 

# form_errors.html

{% if form.errors %}
    {% for field in form %}
        {% for error in field.errors %}  <!-- 필드 오류를 출력한다. -->
            <div class="alert alert-danger">
                <strong>{{ field.label }}</strong>
                {{ error }}
            </div>
        {% endfor %}
    {% endfor %}
    {% for error in form.non_field_errors %}   <!-- 넌필드 오류를 출력한다. -->
        <div class="alert alert-danger">
            <strong>{{ error }}</strong>
        </div>
    {% endfor %}
{% endif %}

# signup.html

{% extends "base.html" %}
{% block content %}
<div class="container my-3">
    <div class="row my-3">
        <div class="col-4">
            <h4>계정생성</h4>
        </div>
        <div class="col-8 text-right">
            <span>또는 <a href="{% url 'common:login' %}">로그인 하세요.</a></span>
        </div>
    </div>
    <form method="post" class="post-form">
        {% csrf_token %}
        {% include "common/form_errors.html" %}
        <div class="form-group">
            <label for="username">사용자 이름</label>
            <input type="text" class="form-control" name="username" id="username"
                   value="{{ form.username.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="password1">비밀번호</label>
            <input type="password" class="form-control" name="password1" id="password1"
                   value="{{ form.password1.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="password2">비밀번호 확인</label>
            <input type="password" class="form-control" name="password2" id="password2"
                   value="{{ form.password2.value|default_if_none:'' }}">
        </div>
        <div class="form-group">
            <label for="email">이메일</label>
            <input type="text" class="form-control" name="email" id="email"
                   value="{{ form.email.value|default_if_none:'' }}">
        </div>
        <button type="submit" class="btn btn-primary">생성하기</button>
    </form>
</div>
{% endblock %}

 

7. 로그인, 로그아웃 후 리다이렉트 처리하기

# settings.py (홈으로 이동)

LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

 

 

출처: wikidocs.net/book/4223 (점프 투 장고)

 

+ Recent posts