인프런 커뮤니티 질문&답변

김도하님의 프로필 이미지

작성한 질문수

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

Custom User Model 관련 권한 Field 추가

해결된 질문

작성

·

260

0

안녕하세요.

기본 유저 모델로는 다 포용하지 못하는 부분이 있어 커스텀 유저 모델을 만드려고 하고 있습니다. 기본 유저 모델의 경우 staff, superuser 두 개의 권한이 있는 것으로 알고 있는데, manager 권한을 한 개 더 부여해야 하는 상황입니다.

아래와 같이 코드를 구현하여 보았는데, 부족한 부분이나 잘못된 부분이 있는지 봐주시면 감사합니다.

from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.core.mail import send_mail
from django.utils.translation import gettext_lazy as _
from django.utils import timezone


class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, username, email, password, **extra_fields):
        if not email:
            raise ValueError("Email을 입력해주세요.")

        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_user(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_manager', False)
        extra_fields.setdefault('is_superuser', False)

        return self._create_user(username, email, password, **extra_fields)

    def create_staff(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_manager', False)
        extra_fields.setdefault('is_superuser', False)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('is_staff=True일 필요가 있습니다.')

        return self._create_user(username, email, password, **extra_fields)

    def create_manager(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_manager', True)
        extra_fields.setdefault('is_superuser', False)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('is_staff=True일 필요가 있습니다.')
        if extra_fields.get('is_manager') is not True:
            raise ValueError('is_manager=True일 필요가 있습니다.')

        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_manager', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('is_staff=True일 필요가 있습니다.')
        if extra_fields.get('is_manager') is not True:
            raise ValueError('is_manager=True일 필요가 있습니다.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('is_superuser=True일 필요가 있습니다.')

        return self._create_user(username, email, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(_("username"), max_length=50, validators=[username_validator])
    email = models.EmailField(_("email_address"), unique=True)
    is_staff = models.BooleanField(_("staff_status"), default=False)
    is_manager = models.BooleanField(_("manager_status"), default=False)
    is_active = models.BooleanField(_("active"), default=False)
    date_joined = models.DateTimeField(_("date_joined"), default=timezone.now)
    created_at = models.DateTimeField(_("create"), auto_now_add=True)
    updated_at = models.DateTimeField(_("update"), auto_now=True)

    objects = UserManager()
    USERNAME_FIELD = "email"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = ['username']

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

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

답변 1

0

이진석님의 프로필 이미지
이진석
지식공유자

안년하세요.

쓰신 것처럼 is_manager 플래그를 추가해보셔도 좋겠고 (코드 잘 쓰신 듯 합니다.)

본 강의에서 언급된 장고의 기능은 아니지만, group 단위로 권한 시스템을 적용해보셔도 좋습니다. manager 외에 다양한 그룹을 두고, 그룹 단위로 가용한 권한을 세팅한다면 좋은 접근입니다.

화이팅입니다. :-)

김도하님의 프로필 이미지
김도하
질문자

코드는 검색해서 찾은 코드에 필요한 부분들만 추가 수정 작업한 코드입니다.(스스로 다 만든건 ㅠ)

관련 docs를 살펴보니 권한 부여에도 디테일하게 들어가는 부분들이 있네요... 당장은 깊게 들어가는게 어려우니 코드에 문제가 없으니 일단 진행해봐야 겠습니다. 감사합니다!