Django - User 모델을 이용한 Signup, User 확장

nathan·2021년 7월 16일
1

Django

목록 보기
16/22

이번엔 회원가입 기능을 구현하여 보자.

회원가입도 로그인과 마찬가지로 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 %}
- 로그인이 되지 않았을 때는 회원가입 버튼까지 잘 뜨는 것이 확인된다.
  • 회원가입 버튼을 클릭하면 다음과 같은 화면이 출력된다.
    • 나중에 CSS를 통해 수정이 가능하니 참고하도록 하자.

User 모델 확장

  • 지금까지 장고에서 기본적으로 제공하는 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 클래스를 상속해 값을 추가해 줄 수 있다.

  • 상속이란?

    • 간단하게 말해, 기존에 정의된 클래스의 내용들을 그대로 물려받는 것을 말한다.
    • 여기선 User 모델의 클래스를 그대로 물려받아 새로운 값을 추가한다는 것
    • 참고 : 코딩도장 - 클래스 상속

  • 다음으로, 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 완료 후 해당 부분의 주석처리를 꼭 다시 풀어주도록 하자.


    forms.py 작성

  • 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을 만들었다.
  • 기존 User 모델에 존재했던 username, password1, password2 이외에, 새로 정의한 nickname, university, location 필드를 추가했다.
  • 이렇게 변경된 내용을 account/views.py에도 적용하자.
 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하자.
  • 새로운 field가 추가된 것을 확인할 수 있다.

마지막으로 로그인 된 사용자에 한하여 인사를 해주는 코드를 작성하자.
{% if user.is_authenticated %} : 로그인이 되어있는지 물어보는 코드

blog/home.html

{% if user.is_authenticated %}
      {{user.location}}에 사는 {{user.university}}다니는 {{user.nickname}} 안녕하세요!
{% endif %}
  • 이를 응용해서 회원/비회원에게 각각 다른 화면을 보여줄 수 있는 것이다.

Admin 페이지에 모델 등록하기

  • Admin 페이지에서 데이터를 관리할 수 있었다는 것을 배운적이 있다.
  • 마찬가지로 가입된 회원 정보도 관리할 수 있다.
  • account 앱의 admin.py에서 모델을 등록해줍시다.

account/admin.py

from django.contrib import admin
from .models import CustomUser
# Register your models here.

admin.site.register(CustomUser)
profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글