하루에는

[Django]장고 Users(유저) 모델 본문

Python, Django

[Django]장고 Users(유저) 모델

에는 2019. 12. 10. 11:09

Overviews

  • 장고 유저 모델 사용하기
  • account 앱을 만들어 회원가입, 로그인, 로그아웃 구현하기

account 앱 만들기

account 앱은 회원가입, 로그인 등의 기능을 가진 앱입니다.

python manage.py startapp account

앱을 만들었으니 settings.py의 INSTALLED_APPS에 등록해주고, urls 설정도 해줍니다.

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'picker.apps.PickerConfig',
    'post.apps.PostConfig',
    'account.apps.AccountConfig', # 추가
]
# settings.py가 있는 프로젝트 폴더의 urls.py

from django.contrib import admin
from django.urls import path, include
import picker.views
import post.views
import account.views # 추가

urlpatterns = [
    path('admin/', admin.site.urls),
    path('picker/', include('picker.urls')),
    path('post/', include('post.urls')),
    path('account/', include('account.urls')), # 추가
]
# account/urls.py

from django.urls import path
from . import views

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

회원가입 기능을 구현할 거라서 signup path를 만들어줬습니다.

회원가입 구현

Templates 설정


account 앱에 templates 폴더를 만들고, signup.html을 만들어줍니다.

<!-- sighup.html -->

{% extends 'base.html' %}
{% block content %}

<form action="{% url 'signup' %}" method='POST'>
    {% csrf_token %}
    Username:
    <input type='text' name='username'/><br/>
    Password1:
    <input type='password' name='password1'/><br/>
    Password2:
    <input type='password' name='password2'/><br/>
    <input type='submit' value='가입'/>
</form>

{% endblock %}
  • {% csrf_tocken %} : 장고가 제공하는 템플릿 태그 형식의 csrf tocken

View 설정


account/views.py에 코드를 추가합니다.

from django.shortcuts import render, redirect # 추가
from django.contrib.auth.models import User # 추가
from django.contrib import auth # 추가

# Create your views here.
def signup(request):
    if request.method == 'POST':
        if request.POST['password1'] == request.POST['password2']:
            user = User.objects.create_user(
                request.POST['username'], password=request.POST['password1'])
            auth.login(request, user)
            return redirect('postlist')
    return render(request, 'signup.html')
  • redirect 메서드를 사용하기 위해 redirect 임포트
  • User 모델을 임포트하면 바로 사용 가능
  • auth 기능을 사용하기 위해 auth 임포트
  • User.objects.create_user()에서 새로운 유저 생성
  • auth.login()에서 로그인
  • 로그인 성공 후 postlist로 redirection

base.html에 회원가입 링크도 추가해두었습니다.

가입 버튼을 누르면

postlist로 성공적으로 리다이렉트 되었습니다.

Template 설정

base.html에 유저가 로그인했는지에 따라 다른 메뉴를 띄워보겠습니다.

<h2>base.html에 작성된 네비게이션바</h2>
<a href="{% url 'picker:pick' %}">picker 앱으로 이동</a><br/>
<a href="{% url 'postlist' %}">post 앱으로 이동</a><br/>

{% if user.is_authenticated %}
    <p>{{request.user.username}}님 안녕하세요!</p>
    <a href="#">로그아웃</a><br/>
{% else %}
    <a href="{% url 'signup' %}">회원가입</a><br/>
    <a href="#">로그인</a><br/>
{% endif %}


{% block content %}
{% endblock %}
  • user.is_authenticated : 장고가 제공하는 로그인 여부를 묻는 템플릿 태그. 유저가 로그인 되어있다면 True, 로그인하지 않았다면 False 리턴
  • request.user : 현재 로그인한 유저
  • request.user.username : 현재 로그인한 유저의 username 필드

로그아웃 구현

현재는 회원가입을 진행했으므로 로그인 한 상태입니다.

from django.urls import path
from . import views

urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('signout/', views.signout, name='signout'), # 추가
]

View 설정

signout이 POST로 요청됐을 때 로그아웃 시키도록 합니다.

def signout(request):
    if request.method == 'POST':
        auth.logout(request)
        return redirect('postlist')
    return render(request, 'signup.html')
  • auth.logout(request) : 현재 로그인한 유저 로그아웃시킴
  • 로그아웃 후 회원가입 페이지로 리다이렉트

Template 설정

임의로 자바스크립트를 사용해서 로그아웃 링크를 누르면 POST 요청이 가게 만들었습니다.

<h2>base.html에 작성된 네비게이션바</h2>
<a href="{% url 'picker:pick' %}">picker 앱으로 이동</a><br/>
<a href="{% url 'postlist' %}">post 앱으로 이동</a><br/>

{% if user.is_authenticated %}
    <p>{{request.user.username}}님 안녕하세요!</p>
    <a href="javascript:{document.getElementById('logout').submit()}">로그아웃</a>
    <form id="logout" action="{% url 'signout' %}" method="POST" >
        {% csrf_token %} <input type="hidden" />
    </form>
{% else %}
    <a href="{% url 'signup' %}">회원가입</a><br/>
    <a href="#">로그인</a><br/>
{% endif %}


{% block content %}
{% endblock %}

로그인 구현

account/urls.py에 signin path를 추가해줍니다.

from django.urls import path
from . import views

urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('signout/', views.signout, name='signout'),
    path('signin/', views.signin, name='signin'), # 추가
]

Template 설정

account/templates에 signin.html을 만듭니다.

<!-- signin.html -->

{% extends 'base.html' %}
{% block content %}

<form action="{% url 'signin' %}" method='POST'>
    {% csrf_token %}
    Username:
    <input type='text' name='username'/><br/>
    Password:
    <input type='password' name='password'/><br/>
    <input type='submit' value='로그인'/>
</form>

{% endblock %}

View 설정

def signin(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = auth.authenticate(request, username=username, password=password)
        if user is not None:
            auth.login(request, user)
            return redirect('postlist')
        else:
            return render(request, 'signin.html', {'error': '입력 정보가 잘못되었습니다.'})
    else:
        return render(request, 'signin.html')
  • 요청이 GET으로 들어왔다면 로그인 화면을 띄우고, POST로 들어왔다면 로그인 진행
  • request.POST['변수명'] : form에서 넘겨주는 값의 name을 받는 방법. get 방식으로 넘겨줬다면 request.GET['변수명']으로 받는다.
  • auth.authenticate(request, username=username, password=password) : 해당 유저가 있는지를 검사한다.
  • auth.login() : 로그인
  • 입력한 정보의 유저가 존재하지 않는다면 error 변수를 가지고 다시 로그인 화면 렌더링

Template 설정

{{error}}를 위한 템플릿 태그들을 추가한다.

{% extends 'base.html' %}
{% block content %}

<form action="{% url 'signin' %}" method='POST'>
    {% csrf_token %}
    Username:
    <input type='text' name='username'/><br/>
    Password:
    <input type='password' name='password'/><br/>
    <input type='submit' value='로그인'/>
</form>

{% if error %}
    {{error}}
{% endif %}

{% endblock %}

잘못 로그인한 모습

로그인이 성공한 모습

Comments