본문 바로가기

[Python] django 게시판 로그인 페이지 만들기

액트 2022. 10. 28.
반응형

고 게시판 로그인과 로그아웃 페이지 만드는 방법입니다.

작업 순서는 다음과 같습니다.

  1. common 앱 생성
  2. 로그인 페이지 이동을 위한 링크 생성
  3. 로그인 페이지 생성
  4. url 매핑
  5. 로그인 기능 구현
  6. 로그아웃

장고의 로그인, 로그아웃을 도와주는 앱은 django.contrib.auth 입니다. django.cointrib.auth 앱을 이용하면 로그인과 로그아웃 기능을 정말 쉽게 구현이 가능합니다.

이 앱은 장고 프로젝트 생성시 다음처럼 자동으로 추가됩니다.

경로 mysite\config\settings.py

pybo 프로젝트를 포함한 다른 프로젝트에서도 로그인 로그아웃 기능을 이용할 수 있게 common 이라는 앱을 구현하여 기능을 작성합니다.

 

1. common 앱 생선

common 앱을 신규로 생성합니다.

(myvenv) c:\projects\mysite>django-admin startapp common

common 앱을 생성하면 pybo 앱과 동일한 구조의 디렉터리와 파일들이 자동으로 생성됩니다.

그리고 mysite\config\settings.py 파일에 생성한 common 앱을 등록합니다.

INSTALLED_APPS={} 항목에 'common.apps.CommonConfig', 를 추가합니다.

 

2. 로그인 페이지 링크 생성

웹페이지를 로그인 화면으로 이동할 수 있게 네이게이션 바에 로그인 링크를 생성합니다.

mysite\templates\navbar.html 파일을 아래와 같이 수정합니다.

<a class="nav-link" href="{% url 'common:login' %}">로그인</a>

로그인 버튼을 클릭하면 url 매핑에 의해 common의 login 페이지로 이동하는 구문입니다.

전체 코드

<!-- 네비게이션바 -->
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
    <div class="container-fluid">
        <a class="navbar-brand" href="{% url 'pybo:index' %}">Pybo</a>
        <button class="navbar-toggler" type="button"
                data-bs-toggle="collapse"
                data-bs-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent"
                aria-expanded="false"
                aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <!-- 로그인 페이지 링크 시작 -->
                    <a class="nav-link" href="{% url 'common:login' %}">로그인</a>
                    <!-- 로그인 페이지 링크 끝 -->
                </li>
            </ul>
        </div>
    </div>
</nav>

 

3. 로그인 페이지 템플릿 생성

경로는 mysite\templates\ 하위에 common 디렉터리를 생성하고 로그인 페이지인 login.html 파일을 신규로 생성합니다.

mysite\templates\common\login.html 페이지를 아래와 같이 수정합니다.

{% extends "base.html" %}
{% block content %}
<div class="container my-3">
  <form method="post" action="{% url 'common:login' $}">
    {% csrf_token %}
    <div class="mb-3">
      <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="mb-3">
          <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 %}

사용자ID와 비밀번호를 입력 받아 로그인하는 템플릿입니다. 로그인에 사용되는 사용자ID를 의미하는 username과 비밀번호를 의미하는 password 항목은 django.contrib.auth 앱이 요구하는 필수 항목입니다.

추가로 로그인 실패 시 로그인이 왜 실패했는지 알려주는 역할을 하는 페이지를 생성해야 합니다. 오류에는 다음과 같이 두 가지 종류의 오류가 있습니다.

  • 필드 오류 (field.errors) - 사용자가 입력한 필드 값에 대한 오류로 값이 누락되었거나 필드의 형식이 일치하지 않는 경우 발생하는 오류입니다.
  • 넌필드 오류 (form.non_field_errors) - 필드의 값과는 상관없이 다른 이유로 발생하는 오류입니다. 

이 두 가지 종류의 오류를 표시할 수 있는 템플릿을 작성합니다.

mysite\templates\ 경로 하위에 form_errors.html 파일을 신규로 생성하고 아래와 같이 작성합니다.

mysite\templates\form_errors.html

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

로그인 실패 오류를 나타내는 템플릿 파일을 login.html 파일에 추가합니다.

login.html 파일에 {% csrf_token %} 바로 아래에 다음과 같이 수정합니다.

{% include "form_errors.html" %}

 

4. 로그인 페이지 URL 매핑

이제 페이지는 다 만들었으니 실제 이동하는 링크 url 매핑을 만들어보겠습니다.

로그인 페이지는 common 프로젝트에 있으므로 urls.py 에 다음과 같이 추가합니다. 

path('common/', include('common.urls')),

이제 http://loclahost:8000/common/ 으로 시작하는 URL 주소는 모두 common/urls.py 파일을 참조할 것입니다.

이제 mysite\common\urls.py 파일을 신규로 생성하고 아래와 같이 작성합니다.

from django.urls import path
from django.contrib.auth import views as auth_views

app_name = 'common'

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

로그인 뷰는 별도로 만들지 않고 django.contrib.auth 앱에서 제공해주는 LoginView를 사용합니다.

 

여기까지 작성을 완료했다면 저장 후 서버를 재시작합니다.

로그인 버튼을 클릭하여 로그인 페이지가 아래와 같이 정상적으로 뜨는지 확인합니다.

 

5. 로그인 기능 구현

사용자ID와 비밀번호를 모두 빈 공간으로 두고 로그인 버튼을 클릭하면 아래와 같이 필수 항목 값이라는 메시지가 출력됩니다.

현재 로그인이 가능한 사용자는 슈퍼유저로 생성한 "admin"뿐입니다. 사용자 ID에 admin 을 입력하고 비밀번호을 입력하면 로그인이 가능합니다.

슈퍼유저로 로그인하기 앞서 로그인 버튼을 클릭하여 로그인에 성공하면 이동할 페이지를 설정해줘야 합니다.

설정하지 않으면 django.contrib.auth 패키지에서 디폴트로 설정해놓은 /accounts/profile/ 이라는 URL로 이동합니다.

설정은 mysite\config\settings.py 에서 합니다.

settings.py 파일의 맨 마지막 줄에 다음과 같이 추가합니다.

# 로그인 성공후 이동하는 URL
LOGIN_REDIRECT_URL = '/'

그리고 http://localhost:8000/ 페이지를 접속하시면 URL 매핑 규칙을 작성하지 않아 오류가 발생합니다. 

config/urls.py 파일에 / 페이지에 해당하는 URL 매핑 규칙을 다음과 같이 추가합니다.

from pybo import views

urlpatterns = [] 항목에

path('', views.index, name='index'),  # '/' 에 해당되는 path

을 추가합니다.

서버를 재시작하고 로그인이 잘되는지 확인하시길 바랍니다.

로그인이 성공했다면 http://localhost:8000 페이지가 활성화될 것입니다.

하지만, 여전히 아래 사진과 같이 로그인 버튼이 보일 것입니다.

 

6. 로그아웃

로그인에 성공했다면 "로그인"이 아닌 "로그아웃" 링크로 바뀌어야 합니다.

반대로 로그아웃 상태에서는 "로그인" 링크가 보여야 정상입니다.

navbar.html 템플릿 파일에서 로그인 링크 부분을 다음과 같이 수정합니다.

<li class="nav-item">
	<!-- 로그인 페이지 링크 시작 -->
    {% if user.is_authenticated %}
    <a class="nav-link" href="{% url 'common:logout' %}">{{ user.username }} (로그아웃)</a>
    {% else %}
    <a class="nav-link" href="{% url 'common:login' %}">로그인</a>
    {% endif %}
    <!-- 로그인 페이지 링크 끝 -->
</li>
{% if user.is_authenticated %}

위 구문은 현재 사용자가 로그인 되었는지를 판별하는 구문입니다. 따라서 로그인이 되어 있으면 "로그아웃" 링크를 표시하고 로그인이 되어 있지 않다면 "로그인"링크를 표시합니다.

로그아웃 링크가 추가되었으므로 {% url 'common:logout' %} 에 대응하는 URL 매핑을 common/ulrs.py 파일에 추가합니다.

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='common/login.html'), name='login'),
    ### 로그아웃 추가 ####
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

그리고 로그아웃 시 리다이렉트할 위치도 config/settings.py 파일에 추가합니다.

mysite\config\setting.py 수정

# 로그아웃시 이동하는 URL
LOGOUT_REDIRECT_URL = '/'

 

 

이제 로그인과 로그아웃을 테스트해 보시길 바랍니다.

이 글은 점프 투 장고 wikidocs를 보고 정리한 글입니다. 자세한 질문은 점프 투 장고 wikidocs 를 참고해 주세요.

반응형

댓글