본문 바로가기
카테고리 없음

DRF. custom user model(models.py)

by abccoco 2022. 6. 10.

장고 drf custom user model을 models.py에서 만들어 보자

custom user model의 모든 코드들을 기억하긴 너무 어려운 일이다.

각각의 코드들의 의미를 알고 필요한 코드들을 가져와 사용할 수 있도록 정리해보도록 하려 한다.

* 각 코드의 추가적인 해설은 주석으로 작성했다.

 

 

가장 먼저 할 일은 custom user model을 사용하기 위한 import를 해주도록 하자.

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

 

다음으로

custom user model 사용 시에는 UserManager 클래스와

create_user, create_superuser 함수가 정의되어 있어야 한다.

유의할 점은 UserManager 클래스는 마음대로 이름을 정할 수 없다

Manager을 붙이면 장고에서 Manager class 라는걸 인식하기 때문에 꼭 사용법을 지켜주자.

# custom user model을 사용하기 위한 필수 코드이다. 
# 이 코드를 활용할 수 있어야 한다.
class UserManager(BaseUserManager):
    def create_user(self, username, password=None):
        if not username:
            raise ValueError('Users must have an username')
        user = self.model(
            username=username,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    # python manage.py createsuperuser 사용 시 해당 함수가 사용됨
    def create_superuser(self, username, password=None):
        user = self.create_user(
            username=username,
            password=password
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

 

다음으로는 User class를 작성해 보자.

이 코드는 custom user model을 만들기 위해 필수적으로 필요하다.

# custom user model
class User(AbstractBaseUser):
    username = models.CharField("사용자 계정", max_length=50, unique=True)
    password = models.CharField("비밀번호", max_length=128)
    email = models.EmailField("이메일 주소", max_length=100)
    fullname = models.CharField("이름", max_length=20)
    join_date = models.DateField("가입일", auto_now_add=True)

    # is_active가 False일 경우 계정이 비활성화됨
    is_active = models.BooleanField(default=True)

    # is_staff에서 해당 값 사용
    is_admin = models.BooleanField(default=False)

    # a = id로 사용 할 필드 지정.
    # login('a', password)
    USERNAME_FIELD = 'username'

    # creatsuperuser 할때 입력할 필드 지정
    # 필드 지정을 하지 않아도 작성해야 한다.
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return f"{self.username} / {self.email} / {self.fullname}"

    # 거의 수정 하지 않는다
    def has_perm(self, perm, obj=None):  # 로그인 사용자의 특정 테이블의 crud 권한을 설정, perm table의 crud 권한이 들어간다. # admin일 경우 항상 True, 비활성 사용자(is_active=False)의 경우 항상 False
        return True

    # 거의 수정 하지 않는다
    def has_module_perms(self, app_label):  # 로그인 사용자의 특정 app에 접근 가능 여부를 설정, app_label에는 app 이름이 들어간다. # admin일 경우 항상 True, 비활성 사용자(is_active=False)의 경우 항상 False
        return True
    
    # admin 권한 설정
    @property
    def is_staff(self):
        return self.is_admin

 

Hobby class는 당연히 custom user model에서 필수는 아니다.

회원가입 기능이니 취미 class도 하나 추가해 보자

# 취미 : 운동
class Hobby(models.Model):
    name = models.CharField("취미 이름", max_length=20)
    def __str__(self):
        return self.name

 

마지막으로 UserProFile class를 만들어 볼건데 자기소개, 생일, 나이를 저장할 수 있도록 한다.

이걸 User class에 모두 작성하지 않고 따로 class를 만드는 이유는 보안을 위해서다.

위의 User class에는 민감한 비밀번호와 같은 정보가 들어가지만 UserProfile는 사람들이 봐도 괜찮은 정보들이 들어간다.

 User class는 보안을 위해 is_staff 를 걸어주었다.(본인이 아니면 조회를 하지 못하게 해야한다)

# user detail info table
class UserProfile(models.Model):
    # user = models.ForeignKey(User, verbose_name="유저", on_delete=models.CASCADE, unique=True)
    user = models.OneToOneField(User, verbose_name="유저", on_delete=models.CASCADE)
    introduction = models.TextField("자기소개", null=True, blank=True)
    birthday = models.DateField("생일")
    age = models.IntegerField("나이")
    # ManyToMany는 on_delete = , null=Ture가 필요가 없다.
    # 취미 여러개 선택할 수 있도록 M to M 설정을 해준다.
    hobby = models.ManyToManyField(Hobby, verbose_name="취미")

    def __str__(self):
        return f"{self.user.username} 님의 프로필입니다."


# user - user detail : 1:1
# 한 유저가 두 프로필을 가질 수는 없음

 

이렇게 custom user model 완성!

댓글