이번엔 회원가입 기능을 구현하여 보자.
회원가입도 로그인과 마찬가지로 ModelForm
을 이용해 가입 정보를 받아보자.
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) # form = UserCreationForm(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})
사실 이전 블로그 글을 쓸 때와 전혀 다르지 않다.
이게 다 장고에서 UserCreationForm
이라는 ModelForm
을 이미 잘 만들어놓았기 때문에 가능한 일이다.
그렇다면, 완성도 있는 페이지를 위해서 NavBar를 한 번 더 수정하자.
회원가입 버튼이 로그인 된 상태에서는 뜨지 않고, 로그인이 되지 않은 상태에서만 뜨도록 해야 한다.
base.html
{% 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>
<li class="nav-item">
<a class="nav-link" href="{% url 'account:signup' %}" tabindex="-1" aria-disabled="true">회원가입</a>
</li>
{% endif %}
- 로그인이 되지 않았을 때는 회원가입 버튼까지 잘 뜨는 것이 확인된다.
지금까지 장고에서 기본적으로 제공하는 User 모델을 통해 로그인, 로그아웃 그리고 회원가입까지 구현을 해보았다.
하지만 장고의 기본 User 모델은 실제 서비스에서 매우 한정적 이다.
User 모델의 구성 보기
class User(models.Model):
username = models.CharField(max_length=150)
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=150, blank=True)
email = models.EmailField(blank=True)
is_staff = models.BooleanField()
is_active = models.BooleanField()
date_joined = models.DateTimeField()
is_superuser = models.BooleanField()
만약 에브리타임과 같은 서비스를 만들기 위해서는 대학에 대한 정보도 모델에 추가해야하고, 필요에 따라서는 닉네임이나 유저의 위치 정보를 데이터로 저장하고 싶을수도 있다.
지금부터는 이러한 부분을 User 모델에 추가하는 방법을 알아보도록 하자.
먼저 account/models.py
에 해당 내용들을 정의하자.
account/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUser(AbstractUser):
nickname = models.CharField(max_length=100)
university = models.CharField(max_length=50)
location = models.CharField(max_length=200)
장고의 User 모델을 확장하기 위해서는 AbstractUser
클래스를 상속해 값을 추가해 줄 수 있다.
상속이란?
다음으로, settings.py
에 내용을 추가하자.
settings.py
AUTH_USER_MODEL = "account.CustomUser"
방금 account
앱에 만든 CustomUser
모델을 통해 장고에서 제공하는 로그인, 회원가입 등을 위한 auth 기능을 그대로 사용하기 위함이다.
모델에 새로운 것이 적용되었으니, 마이그레이션을 해주도록 하자.
python manage.py makemigrations
python manage.py migrate
❗️❗️기존에 superuser를 생성하며 만들었던 user 모델의 존재 때문에 migrate시 오류가 발생하게 된다.❗️❗️
잠시 피해가기 위해 admin과 관련된 것들을 주석처리 후 다시 migrate하자.
주석처리 할 곳들
modelproject/urls.py 의 path('admin/', admin.site.urls)
modelproject/settings.py 의 INSTALLED_APPS의 'django.contrib.admin'
migrate 완료 후 해당 부분의 주석처리를 꼭 다시 풀어주도록 하자.
User 모델에 새로운 데이터 필드가 추가된 것과 맞추어 새로운 forms.py
를 작성해줘야 한다.
account 앱 내에 form.py
파일을 만들어주고, 해당 내용을 써준다.
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class SignupForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['username', 'password1', 'password2', 'nickname', 'university', 'location']
forms.py
에서는 UserCreationForm
을 상속해 SignupForm
을 만들었다. from .forms import SignupForm # 이 부분 추가
def signup_view(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = form.save()
auth.login(request, user)
return redirect('home')
return redirect('account:signup')
else:
form = SignupForm()
return render(request, 'signup.html', {'form' : form})
UserCreationForm
을 방금 정의했던 SignupForm
으로 대체해주면 된다.SignupForm
을 import하자.마지막으로 로그인 된 사용자에 한하여 인사를 해주는 코드를 작성하자.
{% if user.is_authenticated %}
: 로그인이 되어있는지 물어보는 코드
blog/home.html
{% if user.is_authenticated %}
{{user.location}}에 사는 {{user.university}}다니는 {{user.nickname}} 안녕하세요!
{% endif %}
account/admin.py
from django.contrib import admin
from .models import CustomUser
# Register your models here.
admin.site.register(CustomUser)