Python/Django / / 2023. 1. 26. 14:14

Django 모델 알아보기 - User 모델 및 커스터마이징

Django에서 간단하게 User 모델 만들기

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = 'Lennon'
>>> user.save()

일단 기본적인 장고의 User모델은 django.contrib.auth.models의 User를 import하면 된다. 위의 코드에서 장고 ORM을 사용해서 create_user메소드를 사용해 간단하게 만들 수 있다. 위의 경우 user모델에 'john', 'lennon@thebeatles.com', 'johnpassword'를 넣어서 간단하게 User 모델을 만든 경우이다. 그러면 궁금한 분들이 계실 것이다, 바로 이 User모델은 기본적으로 어떤 필드 가지고 있을 것인가? 이다. 그것을 아래에서 차근차근 하나씩 설명해 보려고 한다.


디폴트 User 모델

*이 부분은 장고의 Docs를 참조하는 것을 추천합니다.

username

필수, 150자 이하의 필드이다. 만약 150자 이상이 필요한 경우라면 커스텀 유저 모델을 사용하는 것이 좋다. 만약 MySQL을 utf8mb4과 같이 사용한다면, max_length=191을 최대로 설정해야 한다.

first_name, last_name

옵션, 150자 이하의 필드이다.

email

옵션, 이메일 필드이다.

password

필수, 비밀번호의 메타데이터, 해시이다. (장고는 해시되지 않은 raw 패스워드를 저장하지 않는다) 더 자세한 것은 https://docs.djangoproject.com/en/4.1/topics/auth/passwords/를 참고하자.

groups, user_permissions

각각, Group하고 Permission을 위한 Many-to-many(다대다) 관계이다.   

is_staff

admin사이트에 입장 가능한지 판별하는 Boolean 값.

is_active

Django에서는 유저 데이터를 바로 삭제하기 보다는, is_active  플래그를 False로 둬서 하는 것을 추천한다. 그 이유는 이 유저 데이터와 연결된 외래키가 있을 경우 외래키 관계가 부셔질수도 있기 때문이다. 만약 inactive(False)인 유저가 로그인하게 허락하고 싶으면, LoginView를 이용해서 AuthenticationForm을 커스터마이징하는 것을 추천한다.

is_superuser

Boolean값으로, 모든 권한을 가진 유저를 뜻한다.

last_login, date_joined

각각 마지막으로 로그인한 DateTime과 유저가 생성된 DateTime을 뜻한다.


User모델 커스터마이징 하기 그 세가지 방법

  • User모델과 일대일 관계를 가지는 모델 생성
  • AbstractUser를 상속받는 모델을 생성
  • AbstractBaseUser를 상속받는 모델을 생성
  • Proxy 모델을 생성

User모델과 일대일 관계를 가지는 모델 생성

만약 User모델과 관련된 정보를 저장하고 싶다면, 일대일 관계를 가지는 모델을 생성하면 된다. 이 일대일 모델은 프로필 모델이라고도 불리며, 유저의 인증과 관련없는 정보를 저장할 때 사용한다. 예를들면, 유저의 닉네임, 소속 등등일 것이다. 

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=100)

이렇게 하면 User모델에 새로운 정보를 추가할 수 있게 된다. 하지만 기존 정보는 그대로 남아있으므로, User모델을 그대로 이용해야 하며, email로 로그인해야되는 것은 변함없다. 그리고 이러한 테이블이 나눠진 경우 웹앱의 퍼포먼스가 나빠진다는 단점이 생긴다.

 

위의 모델을 이용해 만약 ORM을 작성한다면 아래와 같이 작성이 가능하다.

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department

AbstractUser를 상속받는 모델을 생성

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    nickname = models.CharField(max_length=50)
    phone = models.PhoneNumberField(unique = True, null = False, blank = False)

AbstractUser은 User모델에서 동작은 그대로 하지만, 필드만 재정의하고 싶을 때 사용한다. 즉, 기존 필드를 사용하면서 새로 정의한 필드를 추가할 때 사용한다. 이 때 새로운 User모델을 정의했기 때문에, settings.py에다가 AUTH_USER_MODEL = 'app_name.User'를 추가해야 한다.

 

AbstractBaseUser를 상속받는 모델을 생성

AbstractBaseUser같은 경우 로그인 방식의 변경, 원하는 필드들로 유저 모델의 구현 등등 완전한 커스터마이징을 하고 싶을 때 사용한다. 즉 코드를 재작성 하는 수준이라고 보면 좋을 것 같다. 필수 필드로서 password 하나의 필드만 설정되어 있다. 

from django.db import models
from django.db.models import CharField, EmailField, BooleanField, UUIDField, DateTimeField
from django.contrib.auth.models import AbstractBaseUser

class User(AbstractBaseUser):
    id = UUIDField(primary_key=True, max_length=64, unique=True, null=False)
    name = CharField(max_length=255, unique=False)
    email = EmailField(unique=True)
    password = CharField(max_length=255, null=False, blank=False)
    is_active = BooleanField(default=True)
    is_staff = BooleanField(default=False)
    is_superuser = BooleanField(default=False)
    created_at = DateTimeField(auto_now_add=True, blank=True)
    updated_at = DateTimeField(auto_now_add=True, blank=True)
    login_at = DateTimeField(auto_now_add=True, blank=True, null=True)
    ethereum_address = CharField(max_length=255, null=True)

위의 코드처럼 아주 자유도가 높은 코드다. 실제로 AbstractBaseUser를 상속받으면, id, last_login, password만 상속받고, 나머지는 스스로 정의해줘야 한다. 

 

Proxy 모델을 생성

기존 User 모델을 직접 상속하며, Meta클래스에서 proxy=True 속성을 추가하여 사용한다. 기존 DB 스키마에 영향을 주지 않으며, 프로젝트 중간에 무언가 추가할 필요가 있다면 사용하기 좋은 방식이다.

 

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

class Person(User):
    objects = PersonManager()

    class Meta:
        proxy = True

    def do_something(self):
        ...

이렇게 장고의 User 모델에 대해 알아봤다. 다음에는 장고에서 사용되는 Permission에 대해 알아보려고 한다. 다음 글에서 보겠다. 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유