1. 회원가입 페이지로 연결되는 링크 추가
이전 게시물에서 만든 login.html 템플릿에 아래 코드를 추가하여 회원가입 페이지로 연결되는 링크를 추가한다.
<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>
2. URL 매핑
login.html 템플릿에 {% url 'common:signup' %} 태그를 추가했으므로 이것에 대응되는 URL 매핑을 urls.py에 추가해주어야한다. 아래와 같이 추가해주면 회원가입 링크 클릭 시 views.signup 함수가 실행된다.
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'),
]
3. forms.py - UserForm 작성
views.signup 함수를 작성하기 전에 회원가입 시 사용할 UserForm을 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", "password1", "password2", "email")
django.contrib.auth.forms 모듈의 UserCreationForm 클래스를 상속하여 UserForm을 만들었다. UserForm을 따로 만들지 않고 바로 UserCreationForm을 사용해도 되지만, 위와 같이 이메일 등의 부가 속성을 추가하기 위해서는 UserCreationForm 클래스를 상송해서 만들어주어야한다.
4. views.py - signup 함수 작성
이제 views.py에 signup 함수를 작성한다.
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from .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})
signup 함수는 GET 요청인 경우 회원가입 화면을 리턴하고, POST 요청인 경우 화면에서 입력한 데이터로 사용자를 생성한다. UserCreationForm의 is_valid 함수는 회원가입 필드값 3개가 모두 입력되었는지, 비밀번호1과 비밀번호2가 같은지, 비밀번호의 값이 비밀번호 생성 규칙에 맞는지 등을 검사한다.
form.cleaned_data.get 함수는 입력값을 개별적으로 얻고 싶은 경우에 사용하는 함수이다. 여기서는 사용자명과 비밀번호를 얻기 위해 사용되었다. 그리고 신규 사용자를 생성한 후 자동 로그인이 될 수 있도록 authenticate와 login 함수가 사용되었다. authenticate와 login 함수는 django.contrib.auth 모듈의 함수로 사용자 인증과 로그인을 담당한다.
5. 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" action="{% url 'common:signup' %}">
{% csrf_token %}
{% include "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 %}
6. 테스트
위에서 작성한 회원가입 화면이 잘 뜨는 것을 확인할 수 있다.
비밀번호와 비밀번호 확인을 다르게 입력하여 생성하기 버튼을 눌러보자. 위에서 작성한 is_valid 함수에 의해 에러 문구가 뜨는 것을 확인할 수 있다.
이미 존재하는 사용자 이름을 입력하거나, 비밀번호를 짧게 입력해도 is_valid 함수가 알아서 걸러준다.
이제 회원가입을 완료한 뒤에 관리자 페이지에 접속한다. 관리자 페이지 중 "사용자" 부분에 위에서 생성한 계정이 추가된 것을 볼 수 있다. 또한 비밀번호는 자동으로 해시값으로 처리된다.
'Web > Django' 카테고리의 다른 글
장고(Django) 로그인, 로그아웃 페이지 구현하기, django.contrib.auth 활용 (0) | 2021.08.04 |
---|---|
장고(Django) 템플릿 필터 생성 및 적용하기 (0) | 2021.08.04 |
장고(Django) Paginator을 활용하여 페이징 기능 구현하기 (4) | 2021.08.04 |
장고(Django) GET과 POST를 활용하여 폼(Form) 작업하기 (0) | 2021.08.03 |
Django(장고) static 디렉터리와 템플릿 상속 및 include 태그 사용 (0) | 2021.08.03 |