AbstractBaseUser

μž₯ν˜„μ›…Β·2023λ…„ 10μ›” 5일
0

🐣 AbstractBaseUser


ν”„λ‘œμ νŠΈμ— 맞게 μ‚¬μš©μž λͺ¨λΈμ„ μ›ν•˜λŠ”λŒ€λ‘œ μ •μ˜ν•΄μ£ΌκΈ° μœ„ν•΄ AbstractBaseUserλ₯Ό μ‚¬μš©ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

DjangoλŠ” λ‚΄μž₯ μ‚¬μš©μž λͺ¨λΈμ„ μ‚¬μš©ν•  μˆ˜λ„ μžˆμ§€λ§Œ,

AbstractBaseUserλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜ν•˜λ©΄, Django의 λ‚΄μž₯ μ‚¬μš©μž λͺ¨λΈμ„ ν™•μž₯ν•˜κ³  μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν•„μš”ν•œ ν•„λ“œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ κΈ°λ³Έ ν•„λ“œλ₯Ό λ³€κ²½ν•˜λŠ” λ“± ν”„λ‘œμ νŠΈμ— λ§žλŠ” κ³ μœ ν•œ 데이터 λͺ¨λΈμ„ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ, μ‚¬μš©μž 인증 μ‹œμŠ€ν…œλ„ ν”„λ‘œμ νŠΈμ— 맞게 직접 κ΅¬ν˜„ν•œ λ°©μ‹μœΌλ‘œ μ œμ–΄ν•  수 μžˆμ–΄ μ‚¬μš©μž λ°μ΄ν„°μ˜ λ³΄μ•ˆμ„ 맘껏 κ°œμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ₯ AbstractBaseUserλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜


"""
'AbstractBaseUser'λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©μž λͺ¨λΈμ„ μ»€μŠ€ν„°λ§ˆμ΄μ§•ν•˜κ³  μ‚¬μš©μž λͺ¨λΈμ„ λ³΄μ•ˆμ μœΌλ‘œ κ°•ν™”ν•˜κ³  μ‚¬μš©μž 인증을 κ°œμ„ ν•˜κΈ° μœ„ν•΄ 'BaseUserManager'λ₯Ό μ‚¬μš©ν•˜κ² μŠ΅λ‹ˆλ‹€.

'AbstractBaseUser'λ₯Ό μƒμ†ν•˜μ—¬ μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜ν•˜λ©΄, μ‚¬μš©μžλͺ…, 이메일 λ“±κ³Ό 같은 κ³ μœ ν•œ μ‹λ³„μžλ₯Ό μ‚¬μš©ν•˜μ—¬ 인증할 수 μžˆμŠ΅λ‹ˆλ‹€.
'BaseUserManager'λ₯Ό 톡해 ν•„μš”ν•œ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ μ‚¬μš©μžλ₯Ό μƒμ„±ν•˜κ³  λΉ„λ°€λ²ˆν˜Έ μ„€μ • 및 λ³€κ²½, μ‚¬μš©μž κ·Έλ£Ή 및 κΆŒν•œ 관리 λ“±μ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ°Έκ³  : https://docs.djangoproject.com/en/4.1/topics/auth/customizing/ ' (μ°Έμ‘° : 'A full example')
"""

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager

import random

class UserManager(BaseUserManager):

    """μ‚¬μš©μž λͺ¨λΈμ„ μƒμ„±ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” 역할을 ν•˜λŠ” ν΄λž˜μŠ€μž…λ‹ˆλ‹€."""
    
    def create_user(self, email, password):
        # 일반 μ‚¬μš©μžλ₯Ό μƒμ„±ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.
        if not email:
            raise ValueError('μœ νš¨ν•˜μ§€ μ•Šμ€ 이메일 ν˜•μ‹μž…λ‹ˆλ‹€.')

        user = self.model(
            email=self.normalize_email(email),                                              # 'normalize_email' : Django의 'django.contrib.auth.models' λͺ¨λ“ˆμ— μžˆλŠ” 'UserManager' ν΄λž˜μŠ€μ— ν¬ν•¨λœ λ©”μ„œλ“œλ‘œ 'AbstractBaseUser' λ˜λŠ” 'BaseUserManager'와 같은 μ‚¬μš©μž λͺ¨λΈ(User λͺ¨λΈ)μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€.
                                                                                            # 이메일 μ£Όμ†Œλ₯Ό μΌκ΄€λœ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ‚¬μš©μžκ°€ "UsEr@ExAmPle.CoM" μ΄λ ‡κ²Œ μž…λ ₯해도 "user@example.com" μ΄λ ‡κ²Œ λ³€ν™˜μ‹œμΌœμ€λ‹ˆλ‹€.
            password=password,
            nickname=f"user!@#${random.randint(1000000000,999999999999999)}!@#$",           # createsuperuser둜 μ‚¬μš©μž 계정을 생성할 λ•Œ, nickname값을 받지 μ•ŠκΈ° λ•Œλ¬Έμ— λ°μ΄ν„°λ² μ΄μŠ€μ— nickname값이 빈 μƒνƒœλ‘œ λ“€μ–΄κ°€λŠ”λ°, 두 번째 createsuperuser둜 μ‚¬μš©μž 계정을 생성할 λ•ŒλΆ€ν„° 빈 값이 또 λ“€μ–΄κ°€κ²Œ 되면 'unique=True'의 속성 λ•Œλ¬Έμ— 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€. 'null=True', 'blank=True'둜 속성을 지정해도 λ˜μ§€λ§Œ, μš”κ΅¬ 쑰건과 λ§žμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μž…λ ₯을 μ•ˆν•΄μ€¬μ„ μ‹œμ— λžœλ€ν•œ κ°’μœΌλ‘œ μ €μž₯λ˜λ„λ‘ μ„€μ •ν•΄μ€λ‹ˆλ‹€. 
        )                                                  
        user.set_password(password)                                                         # 'set_password' : μ‚¬μš©μžμ˜ λΉ„λ°€λ²ˆν˜Έλ₯Ό μ„€μ •ν•˜λŠ” λ©”μ„œλ“œλ‘œ μ‚¬μš©μžκ°€ μ œκ³΅ν•œ λΉ„λ°€λ²ˆν˜Έλ₯Ό μ•ˆμ „ν•˜κ²Œ μ €μž₯ν•˜κΈ° μœ„ν•΄ ν•΄μ‹±(hash)된 ν˜•νƒœλ‘œ μ €μž₯ν•©λ‹ˆλ‹€.
        user.save(using=self._db)                                                           # 'using=self._db' μ˜΅μ…˜ : μ €μž₯ν•  λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ§€μ •ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. / save λ©”μ„œλ“œ : μ‚¬μš©μž λͺ¨λΈ 객체λ₯Ό λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.
        return user

    
    def create_superuser(self, email, password):
        # κ΄€λ¦¬μžλ₯Ό μƒμ„±ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.
        if not email:
            raise ValueError('μœ νš¨ν•˜μ§€ μ•Šμ€ 이메일 ν˜•μ‹μž…λ‹ˆλ‹€.')

        user = self.create_user(
             email=self.normalize_email(email), 
             password=password, 
             )
        user.is_admin = True                                                                # createsuperuser둜 μƒμ„±λœ 계정에 κ΄€λ¦¬μž κΆŒν•œμ„ λΆ€μ—¬ν•©λ‹ˆλ‹€.
        user.save(using=self._db)
        return user
    
"""
μœ„μ˜ (email, password=password,)μ—μ„œ 각 인자 전달 방식이 λ‹¬λΌμ„œ μ •λ¦¬ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

< ν•¨μˆ˜ 호좜 μ‹œ 인자 전달 방식 >

1. ν‚€μ›Œλ“œ 인수 ('μΈμžμ΄λ¦„=κ°’' in python)
ν‚€μ›Œλ“œ μΈμˆ˜λŠ” 인자λ₯Ό ν•¨μˆ˜μ— 전달할 λ•Œ 인자의 이름을 ν•¨κ»˜ μ§€μ •ν•˜λŠ” 방식
인자의 μˆœμ„œμ™€ 상관없이 λͺ…μ‹œμ μœΌλ‘œ μ–΄λ–€ μΈμžμ— μ–΄λ–€ 값을 μ „λ‹¬ν•˜λŠ”μ§€ λͺ…ν™•ν•˜κ²Œ 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.
(email=email, password=password,)

2. μœ„μΉ˜ 인수
μœ„μΉ˜ μΈμˆ˜λŠ” 인자λ₯Ό ν•¨μˆ˜μ— 전달할 λ•Œ 인자의 μˆœμ„œμ— 따라 μ „λ‹¬ν•˜λŠ” 방식
ν•¨μˆ˜ μ •μ˜ μ‹œμ— μ •μ˜λœ λ§€κ°œλ³€μˆ˜μ˜ μˆœμ„œλŒ€λ‘œ 값을 전달해야 ν•©λ‹ˆλ‹€.
( email, password)
"""

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     

class User(AbstractBaseUser):
    """
    μ»€μŠ€ν…€ μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜ν•˜λŠ” ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    
    - email(ν•„μˆ˜) : 둜그인 μ‹œ μ‚¬μš©ν•  μ‚¬μš©μžμ˜ 이메일 μ£Όμ†Œμž…λ‹ˆλ‹€.
    - password(ν•„μˆ˜) : 둜그인 μ‹œ μ‚¬μš©ν•  λΉ„λ°€λ²ˆν˜Έμž…λ‹ˆλ‹€.
    - fullname(ν•„μˆ˜) : μ‚¬μš©μžμ˜ μ΄λ¦„μž…λ‹ˆλ‹€.
    - nickname(ν•„μˆ˜) : μ‚¬μš©μžμ˜ λ‹‰λ„€μž„μž…λ‹ˆλ‹€.
        - λ‹€λ₯Έ μ‚¬λžŒμ˜ λ‹‰λ„€μž„κ³Ό μ€‘λ³΅λ˜μ§€ μ•Šλ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.
    - image : μ‚¬μš©μžμ˜ ν”„λ‘œν•„ μ‚¬μ§„μž…λ‹ˆλ‹€.
    - birthday : μ‚¬μš©μžμ˜ μƒλ…„μ›”μΌμž…λ‹ˆλ‹€.
    - join_date : νšŒμ›κ°€μž… 일자 및 μ‹œκ°„μž…λ‹ˆλ‹€.
        - νšŒμ›κ°€μž… ν•œ μ‹œκ°„μ„ μžλ™μœΌλ‘œ μ €μž₯ν•˜λ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.
    - is_active : 계정 ν™œμ„±ν™” μ—¬λΆ€μž…λ‹ˆλ‹€.
        - True ν˜Ήμ€ Falseλ₯Ό μ €μž₯ν•  수 있으며, κΈ°λ³Έκ°’μœΌλ‘œ Trueλ₯Ό μ €μž₯ν•˜λ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.
    """
    
    email = models.EmailField( 
        verbose_name="이메일",                                                      # 'verbose_name' : ν•„λ“œμ˜ labelμž…λ‹ˆλ‹€. [ 1. λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ— ν‘œμ‹œλ˜λŠ” ν•„λ“œ 이름 지정 2. κ΄€λ¦¬μžνŽ˜μ΄μ§€μ— ν‘œμ‹œλ˜λŠ” ν•„λ“œ 이름 지정 3. μ—λŸ¬λ©”μ‹œμ§€μ— ν‘œμ‹œλ˜λŠ” ν•„λ“œ 이름 지정 4. μ‹œλ¦¬μ–ΌλΌμ΄μ €μ— ν‘œμ‹œλ˜λŠ” ν•„λ“œ 이름 지정]
        max_length=255,
        unique=True,                                                                # 'unique=True' : 같은 λͺ¨λΈ 클래슀의 μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€μ—μ„œ λ™μΌν•œ 값을 κ°€μ§ˆ 수 μ—†λ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
    )
    password = models.CharField(verbose_name="λΉ„λ°€λ²ˆν˜Έ", max_length=255)            # λΉ„λ°€λ²ˆν˜ΈλŠ” ν•΄μ‹±λ˜μ–΄ μ €μž₯되기 λ•Œλ¬Έμ— μ΅œλŒ€ 길이λ₯Ό 길게 μ„€μ •ν•©λ‹ˆλ‹€.
    fullname = models.CharField("이름", max_length=50)
    nickname = models.CharField("λ‹‰λ„€μž„", unique=True, max_length=50)
    profile_img = models.ImageField("ν”„λ‘œν•„ 이미지", null=True, blank=True)
    birthday = models.DateField("생년월일", null=True, blank=True)                  # 'blank=True', 'null=True' 속성을 λΆ€μ—¬ν•˜μ—¬ 'birthday'값을 μ„ νƒμ μœΌλ‘œ 받을 수 μžˆμŠ΅λ‹ˆλ‹€.
    join_date = models.DateTimeField("κ°€μž…μΌ", auto_now_add=True)
    is_admin = models.BooleanField("κ΄€λ¦¬μž κΆŒν•œ μ—¬λΆ€", default=True)
    is_active = models.BooleanField("계정 ν™œμ„±ν™” μ—¬λΆ€", default=True)

    objects = UserManager()                                                         # κΈ°λ³Έ μ‚¬μš©μž 지정 λ§€λ‹ˆμ €(objects 속성에 μ •μ˜)κ°€ μ•„λ‹Œ μ»€μŠ€ν…€ 된 μ‚¬μš©μžμ— λŒ€ν•œ λ§€λ‹ˆμ €λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€. κ΄„ν˜Έ ()λŠ” UserManager 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , 이λ₯Ό objectsλΌλŠ” 속성에 ν• λ‹Ήν•˜λŠ” μž‘μ—… 싀행을 μ˜λ―Έν•©λ‹ˆλ‹€.

    USERNAME_FIELD = 'email'                                                        # 'USERNAME_FIELD' : 둜그인 μ‹œ μ‚¬μš©μž 식별(인증)에 μ‚¬μš©ν•  ν•„λ“œλ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.
    REQUIRED_FIELDS = []                                                            # 'REQUIRED_FIELDS' : μ‚¬μš©μž 생성 및 μŠˆνΌμœ μ € 생성 μ‹œμ— ν•„μˆ˜λ‘œ μž…λ ₯ν•΄μ•Ό ν•˜λŠ” ν•„λ“œ 이름을 리슀트 ν˜•νƒœλ‘œ μ§€μ •ν•©λ‹ˆλ‹€. 
    
    def __str__(self):
        return self.email
    
    def has_perm(self, perm, obj=None):                                             # μ‚¬μš©μž 객체의 νŠΉμ • κΆŒν•œ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€. μ•‘μ„ΈμŠ€ μ œμ–΄ 및 κΆŒν•œ 관리에 μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, κ΄€λ¦¬μž νŽ˜μ΄μ§€μ—μ„œ κ΄€λ¦¬μžμ˜ 등급을 λ‚˜λˆŒ λ•Œ, λ‘œμ§μ„ μΆ”κ°€ν•˜μ—¬ μ •μ˜ν•©λ‹ˆλ‹€.
            return True
    
    def has_module_perms(self, app_label):                                          # μ‚¬μš©μž 객체가 νŠΉμ • μ•±(App) λ˜λŠ” λͺ¨λ“ˆ(Module)에 λŒ€ν•œ κΆŒν•œμ„ 가지고 μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.
        return True
    
    @property                                                                       # @property : λ©”μ„œλ“œλ₯Ό μ†μ„±μ²˜λŸΌ μ ‘κ·Όν•  수 있게 λ§Œλ“€μ–΄μ£ΌλŠ” λ°μ½”λ ˆμ΄ν„° μž…λ‹ˆλ‹€.
    def is_staff(self):                                                             # μ‚¬μš©μžκ°€ κ΄€λ¦¬μžμΈμ§€ μ•„λ‹Œμ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€. '@property' λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό 톡해 is_staff 속성(ν•„λ“œ)λ₯Ό κ°€μƒμ μœΌλ‘œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
        return self.is_admin

πŸ“ Django λ‚΄μž₯ μ‚¬μš©μž λͺ¨λΈ VS AbstractUser VS AbstractBaseUser


1. λ‚΄μž₯ μ‚¬μš©μž λͺ¨λΈ

  • μž₯점

    • μ‚¬μš©μž λͺ¨λΈμ„ λΉ λ₯΄κ³  κ°„λ‹¨ν•˜κ²Œ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κΈ°λ³Έ ν•„λ“œλ₯Ό μ œκ³΅ν•˜μ—¬ 일반적인 μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜ν•˜κΈ° μ ν•©ν•©λ‹ˆλ‹€.
    • 기본적인 μ‚¬μš©μž 관리 및 인증 κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • 단점

    • κΈ°λ³Έ ν•„λ“œ μ΄μ™Έμ˜ μ›ν•˜λŠ” μ»€μŠ€ν…€ ν•„λ“œ μΆ”κ°€λ‚˜ ν•„λ“œ μˆ˜μ •μ΄ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.
    • κΈ°λ³Έ ν•„λ“œκ°€ ν•„μš” μ—†λŠ” 경우 μ ν•©ν•˜μ§€ μ•Šμ€ μ‚¬μš©μž λͺ¨λΈμž…λ‹ˆλ‹€.

2. AbstractUser

이미 μ •μ˜λœ μ‚¬μš©μž 관리 및 인증 λ‘œμ§μ„ μƒμ†ν•˜λ©΄μ„œ ν•„μš”ν•œ ν•„λ“œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 즉, κΈ°λ³Έ μ‚¬μš©μž λͺ¨λΈμ˜ ν™•μž₯μž…λ‹ˆλ‹€.

  • μž₯점

    • μ»€μŠ€ν…€ ν•„λ“œλ₯Ό μ‰½κ²Œ μΆ”κ°€ν•˜κ±°λ‚˜ κΈ°μ‘΄ ν•„λ“œλ₯Ό μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • 일반적인 μ‚¬μš©μž λͺ¨λΈμ„ μ •μ˜ν•˜κ³  싢을 경우 κ°„λ‹¨ν•˜κ²Œ μ •μ˜ν•΄μ€„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  • 단점

    • μ½”λ“œ μž‘μ—…μ΄ μ’€ ν•„μš”ν•©λ‹ˆλ‹€.

3. AbstractBaseUser

Django의 λ‚΄μž₯ μ‚¬μš©μž λͺ¨λΈμ„ μ™„μ „νžˆ λŒ€μ²΄ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

  • μž₯점

    • ν•„μš”ν•œ λͺ¨λ“  ν•„λ“œμ™€ λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€!!!!
  • 단점

    • 기본적인 μ‚¬μš©μž 관리 및 인증 κΈ°λŠ₯도 직접 κ΅¬ν˜„ν•΄μ•Όν•©λ‹ˆλ‹€.

κ°œμΈμ μœΌλ‘œλŠ” AbstractBaseUserκ°€ 제일 맀λ ₯적으둜 λ³΄μž…λ‹ˆλ‹€.

πŸ₯šπŸ£πŸ€πŸ₯πŸ“πŸ”

0개의 λŒ“κΈ€