from django.contrib.auth.models import User
가장 먼저 떠오르는 방법입니다. 그러나 이 방법은 User
모델을 참조하는 좋은 방법이 아닙니다.
Django에서 기본으로 제공하는 User
의 기능은 정말로 간소합니다. 시작은 기본적으로 제공하는 User
를 썼을지 몰라도, 나중엔 보통 User
모델을 커스텀마이징하여 사용하게됩니다.
그런데 한 번 프로젝트 세팅을 기본 User
로 한 후에 커스텀마이징을 위해 settings.AUTH_USER_MODEL
로 변경하게되면, 데이터베이스 스키마를 이에 맞게 재수정해줘야 하는데 의존되는 코드들 때문에 매우 귀찮아져 버립니다.
⚡ 그러므로 당장 User
를 커스텀 및 재정의 할 필요가 없더라도, 아래의 유연한 참조 방법을 프로젝트 시작 때부터 쓰도록 합시다.
2-1. get_user_model()
로 직접 참조는 방법
get_user_model()
: 현재 활성화된 User 모델을 반환하며, 그렇지 않은 경우 User(default) 모델을 반환한다.get_user_model()
사용시 임포트 루프를 발생시키므로 주의한다.from django.db import models
from django.contrib.auth import get_user_model
...
class UserProfile(models.Model): # good
class Meta:
model = get_user_model()
fields = ['username', 'email']
class IceCreamStore(models.Model):
# 다음 행은 임포트 루프를 발생시킵니다.
owner = models.OneToOneField(get_user_model())
title = models.CharField(max_length=255)
# shell_plus 를 통한 확인
>>> get_user_model()
# (1) 기존 User 모델만을 사용 시
<class 'django.contrib.auth.models.User'>
# (2) 커스텀 User 모델을 사용 시 >>> 지금은 요거
<class 'profiles.models.UserProfile'>
2-2. AUTH_USER_MODEL
로 지정 후 참조하는 방법
settings.AUTH_USER_MODEL
을 이용.# settings.py
AUTH_USER_MODEL = 'auth.User'
# models.py
from django.conf import settings
...
class Post(models.Model):
author = models.Foreignkey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
get_user_model
VS settings.AUTH_USER_MODEL
get_user_model()
는 객체 인스턴스를 리턴합니다. Django 앱이 로드되는 그 순간에 실행되기 때문에 반드시 유효한 사용자 모델 객체를 리턴한다는 보장을 하지 않습니다. None이 리턴될수도 있는 것이죠. INSTALLED_APPS가 변경되는 등 캐시에 있는 앱이 다시 로드되는 경우 문제가 생길 확률은 더 높아집니다.
AUTH_USER_MODEL
는 외래키 모델을 전달할 때 문자열로 전달합니다. 외래키가 임포트될 때 모델 클래스 탐색에 실패하면 모든 앱이 로드될 때까지 실제 모델 클래스의 탐색을 미룹니다. 그렇기 때문에 항상 올바른 사용자 모델을 얻을 수 있습니다.
2-3. AbstractUser
의 서브클래스를 생성하는 방법
User
모델을 그대로 유지하면서 단지 몇몇 필드만 추가로 필요할 때 이용.#settings.py
AUTH_USER_MODEL = 'profiles.KarmaUser'
# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy_ as _
class KaramUser(AbstractUser):
karma = models.PositiveIntegerField(verbose_name=_("karma"), default=0, blank=True)