본문 바로가기

내일배움캠프

Django 커스텀 User model 사용하기

django를 이용해서 웹개발 연습을 하거나 과제를 진행할 때, 미리 User모델을 커스텀 해놓는 편이다. 나중에 수정할 일이 있을때 편하기 때문이다.

이번에 발생한 문제는 그것때문에 생긴것이다. 커스텀 User에 필드를 추가했을때, 필수로 입력해야하는 필드가 있다면 createsuperuser로 관리자 계정을 생성할 때 해당 필드에 값이 채워지지 않아 오류가 발생하기 때문이다. 

 

class User(AbstractUser):
    GENDER_SELECT = (
        ('M', 'Male'),
        ('F', 'Female'),
        ('O', 'Other'),
        )
    
    nickname = models.CharField(max_length=50)
    birth_day = models.DateField()
    first_name = models.CharField(max_length=30, blank=False, null=False)
    last_name = models.CharField(max_length=150, blank=False, null=False)
    email = models.EmailField(max_length=254, unique=True, blank=False, null=False)
    gender = models.CharField(max_length=1, choices=GENDER_SELECT, default='O')
    introduce = models.TextField(null=True)
    
    def __str__(self):
        return self.username

 

이번 과제에 사용중인 커스텀 User모델이다. 닉네임, 생일, 성, 이름을 필수입력 필드로 요구하고 있다.

django에서 기본적으로 제공하는 유저모델인 AbstractUser를 상속받아서 만들어졌기 때문에 부모클래스의 소스코드를 한번 살펴보자.

 

class AbstractUser(AbstractBaseUser, PermissionsMixin):
	'''

    objects = UserManager()

	'''

 

내용이 상당히 길기때문에 적절히 생략하고 내용을 확인해보면 위와같은 부분이 있다. object로 Usermanager라는 클래스를 사용하고 있는것같다.

 

class UserManager(BaseUserManager):
	'''

    def create_superuser(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True.")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True.")

        return self._create_user(username, email, password, **extra_fields)

	'''

 

해당 클래스를 살펴보면 create_superuser라는 메서드가 있다. 아마도 이 부분이 superuser를 생성할 때 값을 설정해주는 곳인것 같다. 그렇다면 models.py에서 해당 클래스를 상속받아서 새로운 Usermanager를 생성해주면 되지 않을까?

class CustomUserManager(UserManager):
    def create_superuser(self, username, email=None, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        
        if extra_fields.get("is_staff") is not True:
            raise ValueError("Superuser must have is_staff=True.")
        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True.")
        
        extra_fields.setdefault('nickname', 'Admin')
        extra_fields.setdefault('birth_day', '2000-01-01')
        extra_fields.setdefault('first_name', 'Ad')
        extra_fields.setdefault('last_name', 'Min')
        return self._create_user(username, email, password, **extra_fields)

 

Usermanager를 상속받아서 CustomUserManager를 생성했고 create_superuser메서드를 호출해서 오버라이딩했다. 기존의 create_superuser는 is_superuser와 is_staff만 디폴트값으로 지정해주었지만 오버라이딩을 하면서 커스텀 User모델에서 필수 필드로 요구하는 닉네임, 생일, 성, 이름의 디폴트값을 추가적으로 설정했다.

 

class User(AbstractUser):
    GENDER_SELECT = (
        ('M', 'Male'),
        ('F', 'Female'),
        ('O', 'Other'),
        )
    
    nickname = models.CharField(max_length=50)
    birth_day = models.DateField()
    first_name = models.CharField(max_length=30, blank=False, null=False)
    last_name = models.CharField(max_length=150, blank=False, null=False)
    email = models.EmailField(max_length=254, unique=True, blank=False, null=False)
    gender = models.CharField(max_length=1, choices=GENDER_SELECT, default='O')
    introduce = models.TextField(null=True)
    
    objects = CustomUserManager()
    
    def __str__(self):
        return self.username

 

이제 User로 돌아와서 object를 내가 수정한 CustomUserManager를 사용하도록 하면 된다.

 

admin계정

 

새로운 superuser가 내가 지정한 디폴트값을 가지고 생성되었다!

 

이제 superuser를 생성할 때마다 DB를 수정하고 기본값을 따로 지정해줄 필요가 없게되었다.