6. 로그인 로그아웃 구현하기
- 직접 db로 구현할 수 있지만 복잡하다
- 장고에서 제공하는 라이브러리를 사용하면 쉽게 구현이 가능하다.
로그인, 로그아웃은 큰 범위이기 때문에 pybo에서 이어서 만들지 않고, 새로운 앱으로 만들어 준다.
- 터미널 창에 아래 명령어를 입력해 아래와 같은 디렉터리를 만들어 준다.
cd mysite
django-admin startapp common
세팅 설정
- common 디렉토리를 앱으로써 인식하도록 config/settings.py에 추가해 준다.
- 마찬가지로 common과 연결된 url을 연결해 주기 위해서 config/urls.py에 추가해 준다
- common 디렉터리에 url.py가 없기 때문에 만들고 아래 코드를 넣어준다.
로그인 페이지 링크 연결
- 로그인 버튼을 눌렀을 때 common 파일로 이동해야 하기 때문에 layout.html 파일을 수정한다
<!-- 네비게이션바 -->
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
<div class="container-fluid">
<a class="navbar-brand" href="{% url 'pybo:index' %}">메인페이지</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의 링크를 commn:login으로 지정-->
<a class="nav-link" href="{% url "common:login" %}">로그인</a>
</li>
</ul>
</div>
</div>
</nav>
common/url.py 수정
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = 'common'
urlpatterns = [
#장고에서 지원하는 views 라이브러리를 활용(로그인, 로그아웃, 비밀번호 찾기 & 초기화 등)
path('login/',auth_views.LoginView.as_view(template_name = "common/login.html"), name = "login")
]
login.html 생성
{% extends "base.html" %}
{% block content %}
<div class="container my-3">
<form method="post" action="{% url 'common:login' %}">
{% csrf_token %}
{% include "form_errors.html" %}
<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 %}
로그인 화면
- 위 html 코드 1번째 줄에 extends를 통해 layout을 상속받고
- 위 html 코드 6번째 줄에 include를 통해 에러코드 출력부를 입력받아 아래와 같이 에러 발생 시 출력해 준다.
login url 설정
- 로그인 성공 혹은 로그아웃시에 연결될 url 설정을 아래 그림과 같이 config/setting.py에 추가가 필요하다.
root 설정
- 아직 루트경로에 대한 url을 걸어두지 않았었기 때문에 로그인 버튼을 누를 경우 page not found 에러가 발생한다. config/urls.py에 루트에 대한 연결을 설정해 둔다.
로그아웃 구현하기
- 우선 layout에서 로그아웃을 보이도록 하기 위해 아래와 같이 layout을 수정해 준다.
<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>
실행 결과
url 연동
- common:logout이 존재하지 않기 때문에 common/urls.py의 urlpatterns에 아래와 같은 코드 추가
path('logout/',auth_views.LogoutView.as_view(), name = "logout")
회원가입 구현
1. layout.html 수정
- 로그인 버튼 옆에 회원가입 버튼을 만들어 준다.
- 원래 else문 밑에 common:login 태그 아래에 바로 만들어주려 했으나 a태그가 block 형태이기 때문에 따로 li태그로 묶어서 만들어주었다.
- login이 되어있지 않을 때만 회원가입 버튼이 보인다.
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<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>
<li>
{% if not user.is_authenticated %}
<a class="nav-link" href="#">회원가입</a>
{% endif %}
</li>
</ul>
2. url 설정
- common/urls에 추가
from . import views
urlpatterns[
#...
path('signup/', views.signup, name="signup"),
]
3. 회원가입 Form 형성
- 사용자 입력 형태를 받기 위해 common/forms.py를 생성한다
- 그 후 코드 작성
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class UserForm(UserCreationForm):
# username , password 1 , password 2를 기본적으로 입력 받는다.
# 추가적으로 email을 받을 것인데, 기본값은 아니기에 수동으로 잡아줘야함.
email = forms.EmailField(label="이메일")
class Meta:
model = User
fields = ("username", "password1", "password2", "email")
4. 회원가입 함수 생성
- common/views.py에서 signup 함수 생성
from django.shortcuts import render, redirect
from common.forms import UserForm
from django.contrib.auth import authenticate, login
# Create your views here.
def signup(request):
if request.method == "POST":
form = UserForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get("username")
row_password = form.cleaned_data.get("password1")
# 사용자 인증 담당 : 아이디와 비밀번호가 DB랑 같은지 비교
user = authenticate(username=username , password=row_password)
# 로그인 담당 : 사용자에게 입력받은 request와 인증기록인 user를 통해 로그인 허용 또는 거부
login(request, user)
return redirect("index")
else: # Get 요청일 떄
form = UserForm()
return render(request, "common/signup.html", {"form": form})
5. signup.html 생성
- templates/common밑에 signup.html 파일을 만들고 추가
{% extends "base.html" %}
{% block content %}
<div class="container my-3">
<form method="post" action="{% url 'common:signup' %}">
{% csrf_token %}
{% include "form_errors.html" %}
<div class="mb-3">
<label for="username">사용자 이름</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="password1">비밀번호</label>
<input type="password" class="form-control" name="password1" id="password1"
value="{{ form.password1.value|default_if_none:'' }}">
</div>
<div class="mb-3">
<label for="password2">비밀번호 확인</label>
<input type="password" class="form-control" name="password2" id="password2"
value="{{ form.password2.value|default_if_none:'' }}">
</div>
<div class="mb-3">
<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 %}
실행결과
팁
- 항상 장고의 코드를 확인할 때 config의 urls를 우선 확인하자.
- 안에 있는 urls에 따라 하나씩 따라가 보면 된다.
'Back > Django' 카테고리의 다른 글
5. 템플릿 필터 직접 만들어 보기 + 질문에 답변 개수 표시하기 (0) | 2023.04.19 |
---|---|
4. 게시판 페이징 기능 추가하기 (0) | 2023.04.19 |
3.5 Django 흐름 정리 (0) | 2023.04.19 |
3. 장고 부트스트랩으로 화면 꾸미기 (0) | 2023.04.19 |
2. 장고의 기본 요소 Admin, 렌더링, 동적URL매핑,DB연동 (0) | 2023.04.13 |