AbstractBaseUser vs AbstractUser
처음 Django를 시작하고 User모델을 생성할 때는 위처럼 두 개에 모델에 대해서 잘 이해도 못했고 별생각 없이 아무거나 사용했었는데 이제는 그때보다 많은 걸 알게 되었고 어느 정도 이해를 했다고 생각해서 비교를 해보려 한다.
처음 상속받을때부터 확실히 공부했어야 했는데 그 당시에는 왜 안 했던 것인가..
두 클래스를 쉽게 이해하기 위해서 상속 관계를 알고 가면 쉽게 이해할 수 있다.
아래처럼 위에 있는 models.Model를 상속받아 AbstractBaseUser를 생성하고 생성된 클래스를 가지고 AbstractUser를 생성하는 개념이다.
models.Model > class AbstractBaseUser > class AbstractUser > class User
AbstractBaseUser
AbstractBaseUsers는 언제 사용해야하는가?
애플리케이션에 인증 프로세스의 식별 토큰을 사용자 이름이 아니라 이메일 주소초럼 더 합리적인 방법이 있을 때 사용하면 좋다.
AbstractBaseUser 클래스 구성
class AbstractBaseUser(models.Model)
password =
last_login =
def get_username(self):
def clean(self):
def save(self, *args, **kwargs):
def natural_key(self):
@property
def is_anonoymous(self):
@property
def is_authenticated(self):
def set_password(self, raw_password):
def check_password(self, raw_password):
def set_unusable_password(self):
def has_usable_password(self):
def get_full_name(self):
def get_short_name(self):
def get_session_auth_hash(self):
위의 코드를 보면 알 수 있듯이 변수로는 패스워드랑 최근 로그인 일자만 던져준다.
AbstractBaseUser 모델로 정의하기
아래는 내가 프로젝트를 진행하면서 생성한 User 모델이다.
나는 어드민 페이지를 사용하기 위해 'is_%' 목록들을 생성하였지만 어드민 페이지를 이용하지 않을 것으면 굳이 정의해주지 않아도 된다.
class User(AbstractBaseUser, TimeStampedModel, PermissionsMixin):
email = models.EmailField(_("email address"), unique=True, max_length=256)
name = models.CharField(_("name"), max_length=30, blank=True, null=True)
nickname = models.CharField(
_("nickname"), max_length=15, unique=True, blank=True, null=True
)
profile = models.ImageField(
_("profile image"),
upload_to=upload_user_img,
default="img/default/default_img.jpg",
)
birthday = models.DateField(_("birthday"), max_length=10, blank=True, null=True)
gender = models.IntegerField(default=0, null=True)
phone = models.CharField(max_length=50, null=True, blank=True)
is_active = models.BooleanField(_("active"), default=False)
is_staff = models.BooleanField(_("is_staff"), default=False)
is_superuser = models.BooleanField(_("is_superuser"), default=False)
objects = UserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
- USERNAME_FIELD : 고유 식별자로 사용되는 사용자 모델의 필드 이름을 설명하는 문자열입니다. 필드는 고유해야 합니다(즉, unique=True해당 정의에 설정되어 있음).
- REQUIRED_FIELDS : 관리 명령을 통해 사용자를 생성할 때 표시되는 필드 이름 목록입니다 createsuperuser.
- objects : 과거에는 User.objects.create()를 편하게 사용했지만 위처럼 오버로드 해서 사용해 줄 수 있다.
아래는 objects를 정의해 준 내용이다.
class UserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
if not email:
return ValueError("이메일을 설정해야 합니다")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, **extra_fields):
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
extra_fields.setdefault("is_active", False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", 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(email, password, **extra_fields)
마지막으로 Settings.py를 업데이트해야 한다.
AUTH_USER_MODEL = '앱이름.User'
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = "email"
AbstractUser
AbstractUser는 언제 사용하는가?
Django가 제공하는 프로세스를 완벽하게 사용하고 변경할 필요가 없는 경우에 사용한다.
클래스 구성
기존 AbstractBaseUser를 상속받아 사용하기 때문에 AbstractBaseUser의 내용과 추가적으로 username, firstname 등등 값들을 받는다.
class AbstractUser(AbstractBaseUser, PermissionMixin):
username =
first_name =
last_name =
email =
is_staff =
is_active =
date_joined =
def clean(self):
def get_full_name(self):
def get_short_name(self):
def email_user(self, subject, message, from_email=None, **kwargs):
사용법
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# 추가하고싶은 속성 정의
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
기본적으로 전체 구현이 되어 있으므로 추가하고 싶은 속성만 추가해 두면 된다.
그리고 앞서 진행했던 것처럼 Settings.py를 변경해 준다.
AUTH_USER_MODEL = '앱이름.User'