본문 바로가기
Web/Django

User Model 커스텀 하기

by DUSTIN KANG 2023. 11. 28.

회원 가입, 로그인 기능을 구현하기 위해 인증 기능이 필요하고 이 인증 기능을 구현하기 위해 `User` 정보가 필요하다.

기본적으로, Django에서는 User모델을 제공한다. 하지만, User 정보에 전화 번호나 생년월일을 추가하고 싶을 때가 있다.

이렇게 직접 User 클래스를 생성하는 커스텀 유저 모델을 생성하기 위해 몇가지 방법이 존재한다.

  • AbstractUser : 해당 User 클래스의 필드에서 추가 필드만 생성하는 방식
  • AbstractBaseUSer : 완전히 User 클래스를 커스터마이징 하는 방식

이외에도, 모델 그대로를 상속받는 Proxy Model과 1:1 관계를 유지하는 OnetoOne 모델이 있지만 1:1은 두가지 모델을 서로 참조하기 때문에 느리다는 단점이 있다. 

user Model의 상속을 도식화함.

프로젝트를 시작할 때, 설정해야하며 모델을 만들고 마이그레션이 끝나면 변경할 수 없기 때문에 첫 마이그레이션 전에 확정
해야 한다.  유저 모델 안에 필드들은 나중에 변경해도 좋지만 Auth_User_model 변경은 복잡하다.

기본적인 User 클래스

먼저 User 클래스를 확인해보자.

`Auth_user` 테이블을 보면 User와 관련된 필드를 확인할 수 있다.

따로 user model를 지정하지 않으면 기본적으로 django의 `auth_user` 테이블을 사용해 user를 구현할 수 있다. 

 

기존 Auth_user 테이블의 필드

 

모델 생성

이번에는 `AbstractUser`를 상속받아 이메일로 로그인을 인증해보려고 한다.

만약 `AbstractBaseUser`로 모델을 확장한다면 스스로 하나하나 필드를 구성해야한다. 

 

AbstractUser 모델을 상속받아 사용하는 경우 필요한 것을 더해 만들 수 있음.

class User(AbstractUser):
    """
    회원정보 모델
    """
    nickname = models.CharField(max_length=30, unique=True, null=True)
    email = models.EmailField(max_length=100, unique=True, null=False, blank=False) # unique=True
    profile = models.ImageField(null=True, blank=True)
    is_cons = models.BooleanField(default=False)

    # 헬퍼 클래스
    objects = CustomUserManager()

    # ID로 사용할 필드
    USERNAME_FIELD = 'email' 
    
    # 필수로 입력해야하는 필드
    REQUIRED_FIELDS = ['nickname'] 

    # 관리자 페이지 표시
    def __str__(self):
        return self.email
        
    # 관리자 페이지 접근 권한에 따른 메소드
    def has_perm(self, perm, obj=None):
    	return True
        
    def has_module_perms(self, app_label):
        return True
        
    # DB 테이블 지정
    class Meta:
        db_table = 'auth_user'

 

자. 상위 코드를 하나씩 알아보도록 하자.

  • `USERNAME_FIELD` : 만약 회원이 로그인을 할 때, username이 아닌 email 필드를 사용해야 한다면 `'email'`로 식별자를 지정하면 된다. 반드시, 유저 마다 다른 값이어야 하므로 `unique=True`로 고유값 설정을 해주어야 한다.
  • `REQUIRED_FIELDS` : 유저를 생성할 때 최소한의 필드들을 말한다.
  • `has_perm` : 사용자가 특정 권한이 부여되어 있는지 확인하는 함수이다.
  • `module_has_perms` : 특정 앱이나 모듈에 권한이 있는 확인하는 함수이다. 
  • `objects` : 일종의 유저 매니징 클래스로 유저를 생성할 때 사용하는 헬퍼 클래스이다. 생성된 유저 인스턴스는 모델에 저장된다.

유저 매니저 클래스 작성

실제로 유저를 생성한 다음에야 유저 인스턴스가 모델에 저장된다. 그전에 유저를 생성하는 클래스가 유저 매니저 클래스이며 헬퍼 클래스라고 한다. `User`와 `SuperUser`는 따로 함수를 작성해야 한다.

 

유저 클래스 작성하기

먼저, 유저 클래스를 생성하는 함수이다.

이메일이 작성하지 않은 경우엔  `ValueError`를 발생시키고 작성한 경우에 user를 생성하게끔 작성했다.

유저 모델을 생성할 땐, 비밀번호를 제외한 나머지 필드(`**extra_fields`)를 넣는다. 이메일 주소의 도메인을 소문자로 지정해 정규화했다. 비밀번호는 해싱이 필요하기 때문에 `.set_password`하여 해싱 작업을 진행했다.

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

class UserManager(BaseUserManager):
    """
    이메일 식별자를 이용해 회원을 생성하기 위한 헬퍼 클래스
    """
    def create_user(self, email, password=None, **extra_fields):
        if not email: # 이메일이 없는 경우
            raise ValueError("Users must hava an email!")
            
        user = self.model(
            email=self.normalize_email(email), **extra_fields
        )
        user.set_password(password) # 비밀번호 생성 메서드
        user.save(using=self.db) # auth_user에 회원 정보 저장
        return user

슈퍼유저 클래스 작성하기

`superuser`는 패스워드를 해싱할 필요 없이 `create_user`를 상속받아 권한만 추가해주면 된다. 또는 유저 클래스 처럼 똑같이 작성해도 된다.

    def create_superuser(self, email, password=None,**extra_fields):
        user = self.create_user(
            email= email,
            password = password,
        )
        
        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)
        return user

 

커스텀 모델 지정하기

모델을 정의했으면 settings.py에서 유저 모델로 사용할 모델을 지정해주어야 한다.

AUTH_USER_MODEL = 'users.User'

 


사용자 모델 커스터마이징하기 - DJANGO 공식 문서↗

 

오늘도 저의 포스트를 읽어주셔서 감사합니다. ☕️

설명이 부족하거나 이해하기 어렵거나 잘못된 부분이 있으면 부담없이 댓글로 남겨주시면 감사하겠습니다.

'Web > Django' 카테고리의 다른 글

Django - 객체 참조 관계  (0) 2023.11.29
[Django] CRUD 구현  (0) 2023.11.29
Static 파일 관리하기 with AWS S3 연동하기  (0) 2023.11.27
[Django] 개발환경 세팅하기  (0) 2023.11.22
[Django] 애플리케이션 요청 및 처리  (0) 2023.11.21