Contents

Django_10_CustomAuthUser_AbstractUser

​

Django AbstractUser

이전에 AbstractBaseUser를 사용한 커스텀 사용자 인증 테이블을 구성해보았습니다. 해당 내용에 이어서 AbstractUser로 커스텀 사용자 인증 테이블을 구성해보고 createsuperuser 명령어 입력시, 관리자 계정이 커스텀한 테이블에 생성되게 해보겠습니다.

​

AbstractUser을 상속받아 커스텀을 진행

우선 AbstractUser는 Django에서 기본으로 제공해주는 사용자 인증 테이블의 요소를 그대로 가져와 사용하기 때문에 그 요소들은 어떤 것들이 있는지 알아보자.

id, password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined 총 11개의 column이 존재하며 이외에 column을 추가 하고 싶을 때 코드를 추가로 작성합니다.

전 이전에 AbstractBaseUser의 경우와 같이, 추가로 nickname을 필수로 등록받는 것으로 시작하여 createsuperuser했을 때, myabuser 테이블에 nickname을 필수로 입력받는 관리자 계정이 생기도록 진행해보겠습니다.

​

아래 정리는 이전에 AbstractUser관련 테스트를 진행한 후에 내용입니다. 즉, 프로젝트를 만들고, accounts라는 앱을 만들고, settings.py에 AUTH_USER_MODEL=‘accounts/myabuser’를 등록한 후 진행합니다.

​

🤔 소스 코드를 작성해보려는데 궁금증이 생겼습니다.

  1. AbstractUser도 BaseUserManager가 필요한가?

    소스코드로 확인해보겠습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    
    # accounts/models.py
    
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    # Create your models here.
    class MyAbUser(AbstractUser):
        nickname = models.CharField(max_length=100, default=None)
    

    까지만 설정하고

    1
    2
    3
    
    # Terminal에 명령어 입력
    > python manage.py makemigrations
    > python manage.py migrate
    

    DB를 확인해보니

    nickname column이 생겼고 이제,

    1
    2
    
    # Terminal에 관리자 계정 생성을 시도
    > python manage.py createsuperuser
    

    했더니 제가 원했던 email, nickname, password를 받는 것이 아닌 default로 createsuperuser를 했을 때 입력받는 항목들이 나왔습니다.

    즉, AbstractBaseUser를 사용하든지 AbstractUser을 사용하든지 간에, 최소한 커스텀된 관리자 계정을 생성하기 위해서는 BaseUserManager가 필요하다는 것을 알았습니다.

    ​

  2. createsuperuser를 했을 때 email, nickname, password만 기록한 관리자 계정을 만들 수 있는가?

    우선 BaseUserManager를 추가한 소스코드

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    # accounts/models.py
    
    from django.db import models
    from django.contrib.auth.models import AbstractUser, BaseUserManager
    
    # Create your models here.
    class MyUserManager(BaseUserManager):
        def create_user(self, email, nickname, password=None):
            if not email:
                raise ValueError('Users must have an email address')
    
            user = self.model(
                email=self.normalize_email(email),
                nickname=nickname
            )
    
            user.set_password(password)
            user.save(using=self._db)
            return user
    
        def create_superuser(self, email, nickname, password):
            user = self.create_user(
                email,
                password=password,
                nickname=nickname,
            )
            user.is_admin = True
            user.save(using=self._db)
            return user
    
    class MyAbUser(AbstractUser):
        nickname = models.CharField(max_length=100, default=None)
    
        objects = MyUserManager()
    
        REQUIRED_FIELDS = ['nickname']
    

    모델에 변경사항이 있는 것은 아니니 makemigrations & migrate는 하지 않습니다. 이후에

    1
    2
    
    # Terminal에 관리자 계정 생성을 시도
    > python manage.py createsuperuser
    

    하였지만, REQUIRED_FIELDS에 등록된 nickname을 추가로 받긴 하지만, 아직 email을 필수로 받지 않고, Username이 고윳값(PK)로 설정되어 있는 것 같습니다.

    ​

    그렇다면, 고윳값(PK)를 변경할 수 있는 USERNAME_FIELD를 설정하고

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # accounts/models.py
    
    class MyAbUser(AbstractUser):
        nickname = models.CharField(max_length=100, default=None)
    
        objects = MyUserManager()
    
    	USERNAME_FIELD = 'email'	#👈
        REQUIRED_FIELDS = ['nickname']
    

    createsuperuser를 해보겠습니다.

    1
    2
    
    # Terminal에 관리자 계정 생성을 시도
    > python manage.py createsuperuser
    

    하지만,

    오류가 납니다. email을 unique하게 세팅해야 한다는 말 같아서 email의 필드설정을 해보겠습니다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    # accounts/models.py
    
    class MyAbUser(AbstractUser):
        email = models.EmailField(		   #👈
            verbose_name='email addresss', #👈
            max_length=255,
            unique=True,	               #👈
            default=None,
        )
        nickname = models.CharField(max_length=100, default=None)
    
        objects = MyUserManager()
    
    	USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['nickname']
    

    이제 됩니다. 제가 작성한 코드가 동작하는지 확인하려 일부로 오기재한 ’email addresss’으로 입력을 받고, 제가 원하던 모습인 email, nickname, password만 입력을 받으며 관리자 계정이 생성되었습니다.

    ​

    DB를 확인해보니

    ​

    AbstractUser를 상속받아 커스텀한 사용자 인증 항목 중, Default로 설정되는 값인 is_superuser, is_staff, is_active, date_joinnd를 제외한 email, nickname, password가 입력된 값으로 반영된 것을 확인하였습니다.

    ​

    아마, is_superuser와 date_joined는 필수값이 아니기 때문에 강제로 기록하고 싶지 않다면 방법이 있을 것입니다. 다만 이번에 알아보지는 않겠습니다.

    ​

    이렇게 AbstractUser의 기본적인 사용법을 알아보았습니다.

    ​

    AbstractBaseUser와 AbstractUser의 차이를 알아보았고 코드와 DB의 모습까지 살펴보았습니다. 이 둘의 차이와 장,단점을 이해하는데 많은 도움이 되었으면 합니다.

    ​

    ​

    ​

    ​