일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- GitHub
- Python
- JavaScript
- Bruth Force
- DFS
- Linked list
- Algorithm
- programmers
- 알고리듬
- Trie
- boj
- Vue.js
- gpdb
- Back tracking
- Data Structure
- spring boot
- CSV
- 모의SW역량테스트
- django
- 코딩테스트
- hash table
- 시뮬레이션
- BFS
- SWEA
- 코테
- 알고리즘
- aws
- SQL
- Priority Queue
- 구현
- Today
- Total
hotamul의 개발 이야기
[Django] User Model 커스터마이징 #3 (TDD) 본문
[Django] User Model 커스터마이징 #2 (TDD)에서 test 코드를 작성했고 username
이라는 필수 인자 (field)가 없기 때문에 user model 객체를 생성할 수 없음을 확인했다.
그럼 이제 test가 pass 할 수 있도록 custom User
model, custom UserManager
을 만들어 보자. (UserManager
는 user model 객체를 생성, 저장, return 해주는 클래스라고 #1에서 설명했다)
User
User
클래스는 두 가지 클래스 상속이 필요하다. (python은 다중 상속을 지원한다.)
먼저 app에 models.py
파일을 열고 아래와 같이 필요한 클래스 및 models
를 import 한다.
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser,
PermissionsMixin,
)
class User(AbstractBaseUser, PermissionsMixin):
"""User in the system."""
그리고 email
, name
, is_active
, is_staff
field를 아래와 같이 만든다.
class User(AbstractBaseUser, PermissionsMixin):
"""User in the system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
여기서 max_length
를 255로 설정한 이유는 EmailField
,CharField
가 최대로 가질 수 있는 글자 수가 255 이기 때문이다.
줄여도 상관은 없다.
그리고 email
field가 user
를 생성하기 위한 유일한 key
이므로 unique=True
를 생성자에 추가한다.
여기서 가장 중요한 것은 다음 attribute를 추가해야 한다는 것이다.
class User(AbstractBaseUser, PermissionsMixin):
"""User in the system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
USERNAME_FIELD = 'email'
은 email
field가 유일한 키이며 필수 인자임을 나타낸다.
이제 User
model 클래스를 만들었으니 user model을 생성/관리 하는 UserManager
를 커스터마이징 해보자.
UserManager
UserManager
는 BaseUserManager
클래스가 필요하므로 추가로 import 해준다.
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
PermissionsMixin,
)
그리고 User
클래스를 만들 때처럼 BaseUserManager
를 상속하는 UserManager
클래스를 만들어 준다.
class UserManager(BaseUserManager):
"""Manager for users."""
def create_user(self, email, password=None, **extra_fields):
"""Create, save and return a new user."""
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
self.model(email=email, **extra_fields)
에서 password를 전달하지 않고 set_password
를 사용하는 이유는 encyption 하기 위함이다. set_password
를 사용하면 django framework이 직접 암호화 하여 hashing 하고 DB에서 직접 password를 조회 하면 암호화된 password를 확인할 수 있다. 이렇게 하면 user 들의 password를 안전한게 관리할 수 있다.
UserManager
도 만들었으니 User
에서 직접 만든 UserManager
를 사용한다는 것을 알려주기 위해 objects = UserManager()
를 User
클래스에 추가한다.
그러면 최종 완성본은 아래와 같다.
models.py
최종 코드
"""
Database models.
"""
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
PermissionsMixin,
)
class UserManager(BaseUserManager):
"""Manager for users."""
def create_user(self, email, password=None, **extra_fields):
"""Create, save and return a new user."""
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
"""User in the system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
setting && migration
User
, UserManager
를 만들었다고 끝난것이 아니다. 먼저 이 app에서는 user는 내가 만든 User
를 사용한다는 것을 settings.py
에도 설정해줘야 한다.
settings.py
파일 아무 위치에 아래 코드를 추가한다.
AUTH_USER_MODEL = 'core.User'
여기서 core
는 내가 추가한 app이다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core',
]
이제 makemigrations CLI로 migration 파일을 만들어보자.
python manage.py makemigrations
위 명령어를 터미널에 입력하면 0001_initial.py
이라는 파일이 migrations 디렉토리 아래에 생성됨을 확인할 수 있다.
그리고 python manage.py migrate
명령어를 입력하면 성공적으로 migration이 되었음을 확인 할 수 있다.
만약 docker를 사용하고 있다면 docker volume ls
명령어로 현재 사용중인 volume
을 확인해서 해당 이름을 docker volume rm [사용중인 volume 이름]
을 먼저 하고 python manage.py migrate
를 입력하면 잘 실행됨을 알 수 있다. (docker rm ~
을 하기전 docker-compose down
을 해야 할 수도 있다)
자 이제 커스터마이징이 끝났으니 작성했던 test가 성공하는지 확인해보자
check test pass
python manage.py test
명령어를 실행하면 다음과 같이
...
Ran 5 tests in 0.102s
OK
...
모든 test가 성공함을 확인할 수 있다. (내가 작성한 test는 총 5개 였다 - 1개는 [Django] User Model 커스터마이징 #2 (TDD)서 작성했던 test)
다음은 email normalizing과 email을 빈칸으로 전달했을 때 발생하는 에러들을 잡아보자.
'Dev. > Django' 카테고리의 다른 글
[Django] User Model 커스터마이징 #6 (TDD) (0) | 2022.07.13 |
---|---|
[Django] User Model 커스터마이징 #5 (TDD) (0) | 2022.07.06 |
[Django] User Model 커스터마이징 #4 (TDD) (0) | 2022.07.03 |
[Django] User Model 커스터마이징 #2 (TDD) (0) | 2022.06.30 |
[Django] User Model 커스터마이징 #1 (0) | 2022.06.29 |