Leta Learns

My Playlist | 210721 - 1 본문

멋쟁이사자처럼 9기/Django 실습

My Playlist | 210721 - 1

leta 2021. 7. 21. 16:17

 

1. 새로운 account 프로젝트 세팅

 

account 앱 생성 (기존의 blog앱과 분리하기 위해)

python manage.py startapp account

 

 

앱을 추가했으니 settings.py에 새 앱을 알려주어야 한다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
    'account',
]

 

 

account/urls.py 정의

from django.urls import path
from . import views

app_name = 'account'

urlpatterns = [
    path('signup/', views.signup_view, name='signup'),
    path('login/', views.login_view, name='login'),
]

 

 

[프로젝트]/urls.py에서 account앱의 url을 include를 통해 연결해준다.

 

config/urls.py

from django.contrib import admin
from django.urls import path, include
import blog.views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog.views.home, name='home'),
    path('blog/', include("blog.urls")),
    path('account/', include("account.urls")),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

 

login.html, signup.html 만들기 (templates)

  • base.html을 상속하여 간단한 틀만 만들 것.
  • ModelForm을 사용할 것 ({{form.as_p}})

login.html

{% extends 'base.html' %}

{% block content %}

<h1>로그인 페이지</h1>
<form action="{% url 'account:login' %}" method="POST">
  {% csrf_token %}
  {{form.as_p}}
  <button type="submit">로그인</button>
</form>

{% endblock %}

 

signup.html

{% extends 'base.html' %}

{% block content %}

<h1>회원가입 페이지</h1>
<form action="{% url 'account:signup' %}" method="POST">
  {% csrf_token %}
  {{form.as_p}}
  <button type="submit">회원가입</button>
</form>
{% endblock %}

 

 

html 파일을 만들었으니 account/view.py와 account/urls.py에 새 html파일들을 연결해주어야 한다.

 

account/urls.py

from django.urls import path
from . import views

app_name = 'account'

urlpatterns = [
    path('signup/', views.signup_view, name='signup'),
    path('login/', views.login_view, name='login'),
]

 

account/views.py

from django.shortcuts import render

# Create your views here.
def login_view(request):
	return render(request, 'login.html')

def signup_view(request):
	return render(request, 'signup.html')

account/views.py는 구현하면서 바로 바꿔줄 것이다. 임시로 틀만 짜놓았다.

 

 

 

 

2. login, logout 구현

 

account/views.py 

from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib import auth

# Create your views here.
def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(request=request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = auth.authenticate(
                request = request,
                username = username,
                password = password
            )
            if user is not None:
                auth.login(request, user)
                return redirect('home')

        return redirect('account:login')
    else:
        form = AuthenticationForm()
        return render(request, 'login.html', {'form':form})

기존 BlogForm을 사용했던 것과 마찬가지로 ModelForm을 사용한다.

이번에는 직접 Form을 작성하지 않고 AuthenticationForm을 import해서 사용한다.

 

 

AuthenticationForm에서 받아온 username과 password의 유효성 검사를 한 후,

username, password 라는 두 변수에 저장한다.

form = AuthenticationForm(request=request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')

form.cleaned_data :

더보기

=> is_valid()가 True로 반환되면 해당 데이터들은 form.cleaned_data라는 딕셔너리 값으로 들어온다.

 

 

해당 username과 password에 일치하는 User 모델이 있는지 확인한다.

user = auth.authenticate(
	request = request,
	username = username,
	password = password
)

 

 

User가 존재한다면, 로그인한 후 home 화면으로 이동

            if user is not None:
                auth.login(request, user)
                return redirect('home')

 

 

유효성검사 (form.is_valid())에서 False가 리턴되거나 User가 존재하지 않는 경우, login 화면에 머무른다.

        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = auth.authenticate(
                request = request,
                username = username,
                password = password
            )
            if user is not None:
                auth.login(request, user)
                return redirect('home')

        return redirect('account:login') #이 경우!

 

 

만약 request.method != 'POST'인 경우 (form 데이터가 제출되는 상황이 아니라면),

AuthenticationForm을 form 변수에 담아 login.html에 띄워준다.

    else:
        form = AuthenticationForm()
        return render(request, 'login.html', {'form':form})

 

 

 

 

login을 구현하였으니 이번에는 logout을 구현하기 위해 account/views.py에 logout함수를 추가한다.

def logout(request):
    auth.logout(request)
    return redirect('home')

 

 

account/urls.py에서도 logout에 대한 해당 경로를 추가해주어야 한다.

from django.urls import path
from . import views

app_name = 'account'

urlpatterns = [
    path('signup/', views.signup_view, name='signup'),
    path('login/', views.login_view, name='login'),
    path('logout/', views.logout, name='logout'),
]

 

 

로그인을 한 후 자신의 아이디가 NavBar에 뜨도록 수정해준다.

NavBar는 base.html에서 정의했으므로 여기서 수정해주어야 한다.

 

아래의 코드를 NavBar를 이루고 있는 <li>태그들 끝에 붙여준다. (</ul> 태그 앞)

{% if user.is_authenticated %}
<li class="nav-item">
  <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">{{request.user}}님 안녕하세요!</a>
</li>
<li class="nav-item">
  <a class="nav-link" href="{% url 'account:logout' %}" tabindex="-1" aria-disabled="true">로그아웃</a>
</li>

{% else %}

<li class="nav-item">
  <a class="nav-link" href="{% url 'account:login' %}" tabindex="-1" aria-disabled="true">로그인</a>
</li>
{% endif %}

 

 

로그인 상태의 NavBar

 

로그아웃 상태의 NavBar

 

login, logout 구현 완료.

 

 

 

 

3. Signup 구현

 

회원가입도 로그인과 마찬가지로 ModelForm을 이용하여 가입정보를 받는다.

 

account/views.py 

import UserCreationForm 까먹지 말기

from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.contrib import auth

def signup_view(request):
  if request.method == 'POST':
    form = UserCreationForm(request.POST) #request.POST 대신 data = request.POST도 가능
    if form.is_valid():
      user = form.save()
      auth.login(request, user) #회원가입 후 자동 로그인
      return redirect('home')
    return redirect('account:signup')
    
  else:
    form = UserCreationForm()
    return render(request, 'signup.html', {'form' : form})

 

 

회원가입 버튼이 로그아웃 상태에서만 뜨도록 NavBar를 수정한다.

 

{% endif %} 앞에 회원가입 버튼 코드를 추가한다.

base.html

<li class="nav-item">
  <a class="nav-link" href="{% url 'account:signup' %}" tabindex="-1" aria-disabled="true">회원가입</a>
</li>
{% endif %}

 

 

로그아웃 상태에서 회원가입 버튼이 뜬다.

 

 

 

회원가입 버튼을 누르면 signup.html로 이동한다.

지금은 넘어가고 뼈대를 다 구현한 후 CSS로 꾸며줄 것이다.

 

 

포스팅이 너무 길어질 것 같아 나누어서 포스팅 해야겠다.

 

 

 

'멋쟁이사자처럼 9기 > Django 실습' 카테고리의 다른 글

My Playlist | 210723  (0) 2021.07.25
My Playlist | 210722  (0) 2021.07.23
My Playlist | 210721 - 2  (0) 2021.07.21
My Playlist | 210720  (0) 2021.07.21
Comments