Django User Model

Gom La·2023년 4월 2일
0

장고와 친해지기

목록 보기
5/17
post-thumbnail

🔖 User Model

Django는 백엔드 부분에서 굉장히 중요한 권한과 인증 에 대하여 개발자가 손쉽게 운영할 수 있게 구현되어 있다.

User 모델은 이 권한과 인증 에 대한 사용자의 데이터를 저장하는 테이블(스키마)이다.

개발자가 사용자에 대한 User 테이블(스키마)를 작성할 필요없이 자동으로 생성해 주기 때문에 매우 편하지만, 정해져 있는 User 모델이기 때문에 그대로 사용하기에는 한계가 존재한다.

settings.py

# Application definition
INSTALLED_APPS = [
   "django.contrib.admin",
   "django.contrib.auth",
   "django.contrib.contenttypes",
   "django.contrib.sessions",
		...
]

🔖 4가지 확장 방법

➤ 프록시 모델(Proxy Model)

기존의 User 모델에 추가적인 사용자의 정보를 저장할 필요가 없을 때 사용하는 가장 간단한 방법이다.

특징

  • 테이블 추가, 칼럼 변경 없이 단순한 상속 방식
  • 정렬순서나 필요한 메소드만 추가하기 위해 사용

구현방법
User 모델을 직접 상속하고 class Meta에서 proxy=True속성으로 프록시 모델임을 설정한다.

from django.contrib.auth.models import User
from .managers import PersonManager

class Person(User):
	objects = PersonManager()
    
    class Meta:
    	proxy = True
        ordering = ('first_name', )
        
        def do_something(self):
        	...

정렬을 first_name으로 한다던가, do_something()와 같은 메소드를 추가할 수 있다.

하지만 기존 User 모델의 칼럼은 변경하지 못한다.

➤ User 모델과 일대일 연결(One-to-One)

모델을 추가하여 기존 User 모델과 일대일로 연결시켜 사용자에 대한 정보를 저장하는 방법이다.

특징

  • Django의 로그인, 권한 부여 등을 그대로 사용 가능
  • 기존 모델에 손상을 주지 않으며 새 칼럼 추가 가능

구현방법

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
	user = models.OneToOneField(User, on_delete=models.CASCADE)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)
    ...

➤ AbstractUser 모델

User모델에서 동작은 그대로 하며 필드만 재정의할 때 사용하는 방법이다.

특징

  • 이 방법은 프로젝트 시작 전(첫 migrate 전)에 하는 것이 좋음
  • 기존 User 모델 대신 AbstractUser를 상속받은 모델이 대체함(단 로그인 인증, 권한 등 그대로 사용)
  • 새로운 칼럼을 추가 가능

구현방법

from django.db import models
from django.contrib.auth.models import AbstractUser

class Users(AbstractUser):
	location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

📌 settings.py

AUTH_USER_MODEL = '[app_name].Users'

➤ AbstractBaseUser 모델

완전히 새로운 User 모델을 상속받아 새로 정의하여 사용하는 방법이다.

특징

  • 데이터 테이블에 영향을 많이 준다.
  • 기존 칼럼뿐 아니라 동작까지 모두 구현해야 한다.

구현방법

from __future__ import unicode_literals

from django.db import models
from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import ugettext_lazy as _

from .managers import UserManager

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
    is_active = models.BooleanField(_('active'), default=True)
    avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    def get_full_name(self):
        '''
        Returns the first_name plus the last_name, with a space in between.
        '''
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        '''
        Returns the short name for the user.
        '''
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        '''
        Sends an email to this User.
        '''
        send_mail(subject, message, from_email, [self.email], **kwargs)

User 모델을 관리하는 Manager도 정의해야한다.

from django.contrib.auth.base_user import BaseUserManager

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('The given email must be set')
        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=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', 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 = '[app_name].Users'
profile
인생 개발자 라곰!!

0개의 댓글