Django AbstractBaseUser로 Custom user모델 만드는 방법

Posted by Hide­
2018.06.25 18:28 Coding/Django

이전에 Custom User모델 만드는 방법에 대해서 포스팅했었는데

다시 읽어보니 상당히 부실한 문서였다고 생각이 들어서 다시 한번 자세히 포스팅한다.

장고는 기본적으로 인증에 관련된 유저 모델을 가지고 있다.

하지만 내가 만드는 서비스와 맞지 않은 정보들을 가지고 있을 때는 굳이 그 유저 모델을 사용할 필요도 없으며 사용할 수도 없다.

따라서 기존에 존재하는 모델을 상속받아서 내 입맛에 맞게 수정해줘야 한다.

프록시 모델 등 여러가지가 있지만 기본적으로 AbstractUser와 AbstractBaseUser 두가지를 설명한다.

AbstractUser를 사용하면 아래와 같이 어느정도 기본적으로 사용할 때 필요한 많은 정보들을 같이 준다.


id / password / last_login / is_superuser / username / first_name / last_name / email / is_staff / is_active / date_joined


위와 같이 많은 정보들을 던져준다.

하지만 위와 같은 컬럼들이 모두 필요하지 않은 경우가 있다.

그럴 때 바로 AbstractBaseUser 를 상속받아서 사용하면 된다.

AbstractBaseUser를 상속받으면 아래와 같은 정보가 기본적으로 딸려온다.


id / password / last_login


AbstractUser와 비교해보면 정말 적은 기본 컬럼을 가지고 있다.

하지만 그만큼 나의 서비스에 맞게 수정하기가 쉽다.

오늘의 포스팅에서는 AbstractBaseUser를 상속받아서 Custom User모델을 생성해보겠다.

먼저 user라는 앱을 생성하고 models.py를 연다.


from django.contrib.auth.models import AbstractBaseUser


최상단에 임포트 구문을 사용하여 AbstractBaseUser를 임포트해줘야 한다.


class User(AbstractBaseUser):
# Default : id / password / last_login
USER_TYPE_CHOICES = (
('django', 'Django'),
('facebook', 'Facebook'),
('gmail', 'Gmail')
)


그리고 위처럼 클래스를 생성하고 상속받는다.

나는 추후 소셜 로그인 기능을 추가할 예정이므로 위처럼 USER_TYPE_CHOICES를 추가해줬다.


user_type = models.CharField(
max_length=20,
choices = USER_TYPE_CHOICES,
default = USER_TYPE_CHOICES[0]
)

email = models.EmailField(max_length=100, null=False)
username = models.CharField(max_length=20, unique=True)
phone = models.CharField(max_length=12)

is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)

date_joined = models.DateTimeField(auto_now_add=True)

USERNAME_FIELD = 'username'


is_staff부터 is_superuser는 기본적으로 권한에 관련된 부분이므로 왠만하면 있는게 좋다.

참고로 USERNAME_FIELD에 유저네임으로 사용할 컬럼을 지정해줘야 한다. (그렇지 않으면 에러 발생)

나머지 부분은 타 모델과 같이 컬럼을 추가해주는 구문이므로 설명은 생략한다.

이 상태에서 makemigrations & migrate를 하면 에러가 발생한다.

바로 Manager를 만들지 않았기 때문이다.

Manager를 통해 유저를 생성할때의 행위를 정의해줘야 한다.

models.py에 아래의 내용을 추가한다.


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

class UserManager(BaseUserManager):
def create_user(self, username, email=None, password=None, **extra_fields):
try:
user = self.model(
user_type=User.USER_TYPE_CHOICES[0],
username=username,
email=email,
)
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
user.set_password(password)
user.is_active = True
user.save()
return user
except Exception as e:
print(e)


매니저를 상속받기 위해 BaseUserManager도 임포트 시켜줬다.

create_user를 통해 일반 유저를 생성하는 함수를 오버라이드하여 우리의 데이터와 맞게 수정해줄 수 있다.

다음으로 슈퍼 유저를 만드는 함수를 정의해준다.


def create_superuser(self, username, email=None, password=None, **extra_fields):
try:
superuser = self.create_user(
user_type=User.USER_TYPE_CHOICES[0],
username=username,
password=password,
email=email,
)
superuser.is_admin = True
superuser.is_superuser = True
superuser.is_active = True
superuser.is_staff = True
superuser.save()
return superuser
except Exception as e:
print(e)


나는 처음에 create_superuser를 보면 email도 인자가 있는데 막상 만들려고 하면 email 입력을 받지 않았다.

이런 경우에는 REQUIRED_FIELDS = ['email'] 를 추가해주면 된다.

(여기서 주의할점은 우리가 만든 매니저를 실제 유저 모델에 연결해줘야 한다는 점이다.

class User 의 내용에 objects = UserManager() 를 추가해주면 된다)

마지막으로 settings.py에 우리의 유저모델을 기본 유저모델로 사용하겠다는 라인을 추가한다.


AUTH_USER_MODEL = 'users.User'


makemigrations, migrate 후 어드민 패널에 접속해보면 우리의 User모델이 패널에 등록이 안되어있다.

admin.py를 열어서 아래의 내용을 추가한다.


from django.contrib import admin
from . import models

@admin.register(models.User)
class UserAdmin(admin.ModelAdmin):
pass


그리고 패널에 접속해보면 아래와 같이 정상적으로 출력됨을 확인할 수 있다.



이제 여기서 조회, 추가, 수정, 삭제는 평소 API를 만들던 것 처럼 views, serializers, urls를 작성하여 연결시켜주면 된다.


참고 : https://juliahwang.kr/%EB%AA%A8%EB%82%B4%EA%B8%B0%20%EC%8A%A4%ED%84%B0%EB%94%94/2017/09/22/2.0-%EC%9D%B8%EC%A6%9DAPI%EC%A0%9C%EC%9E%91%ED%95%98%EA%B8%B01.html



다른 사람들이 많이 읽은 글
이 댓글을 비밀 댓글로

티스토리 툴바