Python/DRF

[DRF] 커스텀 유저 구현하기(회원가입/로그인)

emhaki 2023. 1. 14. 23:34
728x90
반응형
SMALL

Django에서는 기본적으로 사용자 모델인 User 모델을 제공하고 있다.

하지만 임의로 원하는 필드(Nickname, birthday 등)을 가진 사용자 모델을 사용하기 위해서는 custom user 모델을 구현해야 한다.

 

custom user 모델을 구현하기 위해서는 BaseUserManager과 AbstractBaseUser 클래스를 상속받아서 새롭게 구현해야 한다.

여기에서 BaseUserManager는 유저를 생성하는 역할을 하는 헬퍼 클래스이고,

AbstractBaseUser는 실제 모델이 상속받아 생성하는 클래스이다. 

 

유저생성을 위해 accounts라는 이름의 앱을 생성해준다.

python manage.py startapp accounts

settings.py

앱을 생성 후 settings.py에 account 앱을 등록시켜준다.

INSTALLED_APPS =[
	'accounts'
]

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager

# Create your models here.
class UserManager(BaseUserManager):
    # 일반 user 생성
    def create_user(self, email, nickname, name, password=None):
        if not email:
            raise ValueError('must have user email')
        if not nickname:
            raise ValueError('must have user nickname')
        if not name:
            raise ValueError('must have user name')
        user = self.model(
            email = self.normalize_email(email),
            nickname = nickname,
            name = name
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    # 관리자 user 생성
    def create_superuser(self, email, nickname, name, password=None):
        user = self.create_user(
            email,
            password = password,
            nickname = nickname,
            name = name
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser):
    id = models.AutoField(primary_key=True)
    email = models.EmailField(default='', max_length=100, null=False, blank=False, unique=True)
    nickname = models.CharField(default='', max_length=100, null=False, blank=False, unique=True)
    name = models.CharField(default='', max_length=100, null=False, blank=False)

    # User 모델의 필수 field
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    # 헬퍼 클래스 사용
    objects = UserManager()

    # 사용자의 username field는 nickname으로 설정
    USERNAME_FIELD = 'nickname'
    # 필수로 작성해야하는 field
    REQUIRED_FIELDS = ['email', 'name']

    def __str__(self):
        return self.nickname

Custom user 모델을 생성하기 위한 코드를 작성했다.

헬퍼 클래스인 UserManager 클래스에서 create user와 create superuser 함수를 통해 일반 user와 관리자 user 객체를 생성하는 코드를 작성해주었다.

AbstractUser인 User 클래스에서는 사용자 모델에 필요한 field를 작성해주었고, USERNAME_FILED, REQUIRED_FILED를 설정해주었다. User클래스의 is_active와 is_admin 필드는 Django User 모델의 필수 field라고 한다.

 

custom user 모델을 생성해준 이후, 마이그레이션을 진행해준다.

python manage.py makemigrations
python manage.py migrate

serializers.py

from .models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        user = User.objects.create_user(
            email = validated_data['email'],
            nickname = validated_data['nickname'],
            name = validated_data['name'],
            password = validated_data['password']
        )
        return user

    class Meta:
        model = User
        fields = ['nickname', 'email', 'name', 'password']

accounts앱 내에 serializers.py를 생성해주고 User모델을 기반으로 serializer를 작성해준다.

serializer의 field로는 회원가입 시 입력을 받고자 하는 nickname, email, name, password로 설정한다.

UserSerializer에서 한 가지 주의해야될 점은 create시(회원가입 시) 입력받은 데이터를 검증해주어야 한다.

validated_data를 통해서 검증하고 User객체를 생성해준다.

views.py

from django.shortcuts import render
from .serializers import UserSerializer
from .models import User
from rest_framework import generics

# Create your views here.
# 회원가입
class UserCreate(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

생성했던 User모델과 UserSerializer를 기반으로 views.py를 작성해준다.

회원가입은 객체를 생성하는 역할을 하기 때문에 generics.py의 CreateAPIView를 상속받아 사용했다.

queryset으로는 User객체를, serializer class로는 UserSerializer를 전달해주었다. 

urls.py (accounts앱 내부)

from django.urls import path, include
from . import views
from rest_framework import urls

urlpatterns = [
    path('signup/', views.UserCreate.as_view()),
    path('api-auth/', include('rest_framework.urls')),
]

urls.py (프로젝트 폴더 내부)

from django.contrib import admin
from django.urls import path, include
from blog import urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('accounts.urls')),
    path('', include('blog.urls')),
]

현재까지 작성한 views.py를 바탕으로 url을 작성한다. 

회원가입을 의미하는 UserCreate를 추가해주고, 로그인을 위해서는 rest_framework에서 제공하는 기능을 활용해준다.

python manage.py runserver를 실행시켜주고,

http://localhost:8000/user/signup/ 로 url을 입력하면

다음과 같이 serializers.py로 커스텀한 Signup페이지가 나오게 된다.

해당사항을 입력하고 POST를 누르게 되면 JSON형식으로 데이터가 넘어가게 된다. 

python manage.py shell

Django shell에 들어가서 User.objects.all()을 해주면 생성한 User 객체를 확인할 수 있다. 

 

참고

https://wisdom-990629.tistory.com/m/entry/DRF-%EC%BB%A4%EC%8A%A4%ED%85%80-%EC%9C%A0%EC%A0%80-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EB%A1%9C%EA%B7%B8%EC%9D%B8

728x90
반응형