티스토리 뷰
이용자와 관리자가 없는 웹사이트는 무용지물에 가깝습니다.
그렇기 때문에 어느 웹사이트를 만들던 User라는 모델은 필수 불가결한 존재입니다.
Django에서는 User에 대한 기본적인 모델과 Authentication을 제공함으로써
Django프레임워크를 통해 웹사이트를 만드려고 하는 사용자가 유저에 대한 기능들을 구현하기 쉽게 해줍니다.
-> user_project django-admin startproject mysite .
장고 프로젝트를 만들고 처음으로 migrate를 하게 되면
프로젝트를 만들고 model에 관련된 부분은 하나도 건들지 않았지만
처음 migrate 했을 시 DB에 여러 테이블을 자동으로 만들게 됩니다.
그중에서 User도 있다는 걸 확인할 수 있습니다.(0003, 0004, 0005, 0008, 0009)
이렇게 Django는 우리가 User모델을 따로 만들지 않아도 자동으로
자신들이 만들어 놓은걸 생성하게 됩니다.
그렇기 때문에 admin페이지로 이동하면 Users라는 탭을 확인할 수 있고
해당 탭에 들어가서 마음대로 User들을 생성할 수 있습니다.
User를 생성해보면
Username, Password, Password confirmation입력 칸이 있는걸 확인할 수 있습니다.
심지어 각 입력칸 아래쪽을 보면
해당 입력 칸에 입력할 내용들에 관한 규정들이 써져있습니다.
만약 그러한 규정들을 지키지 않는다면
장고의 Validator를 통해서 생성을 할 수 없게 합니다.
우린 프로젝트만 생성했을 뿐인데 User를 생성할 수 있고
해당 User에 대한 규정도 미리 정해져 있음으로써 Validator도 자동으로 해줍니다.
class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_("username"),
max_length=150,
unique=True,
help_text=_(
"Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
),
validators=[username_validator],
error_messages={
"unique": _("A user with that username already exists."),
},
)
first_name = models.CharField(_("first name"), max_length=150, blank=True)
last_name = models.CharField(_("last name"), max_length=150, blank=True)
email = models.EmailField(_("email address"), blank=True)
is_staff = models.BooleanField(
_("staff status"),
default=False,
help_text=_("Designates whether the user can log into this admin site."),
)
is_active = models.BooleanField(
_("active"),
default=True,
help_text=_(
"Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts."
),
)
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
위 코드는 실제 Django User모델에 관련된 코드입니다.
우리가 admin페이지에서 가장 먼저 입력할 내용이 username이었는데
AbstractUser클래스를 보면 username필드가 있는 걸 확인할 수 있습니다.
help_text=_(
"Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
),
validators=[username_validator],
username필드 내용 중에 help_text에 써져있는 내용이 익숙하게 느껴지는데
이 텍스트는 아까 admin페이지에서 User를 생성하는 화면에서 볼 수 있었습니다.
필자처럼 Username 입력에 대한 규정을 지키지 않으면 위에 빨간 글씨로
해당 값에 포함할 수 있는 문자들을 알려줍니다.
이러한 Validator로직은 위 코드에서 확인해보면
username_validator = UnicodeUsernameValidator()
username = models.CharField(
validators=[username_validator],
)
UnicodeUsernameValidator()가 한다는 걸 확인할 수 있습니다.
실제로 해당 클래스로 이동해보면
@deconstructible
class UnicodeUsernameValidator(validators.RegexValidator):
regex = r"^[\w.@+-]+\Z"
message = _(
"Enter a valid username. This value may contain only letters, "
"numbers, and @/./+/-/_ characters."
)
flags = 0
regex변수 값에 있는 정규표현식을 보면
해당 정규표현식을 통해 검증을 한다는걸 알 수 있습니다.
심지어 아래 있는 message는 필자가 위에서 보여줬던 Username입력칸의 규정을 잘못 지켰을 시
나타나는 빨간색 글씨로 된 텍스트 내용입니다.
Validator 커스터마이징 해보기
이번에는 실제로 필자가 해당 메시지들을 수정하고 정규 표현식 또한 수정해서
기존의 Validator로직을 바꾼 뒤 다시 admin페이지를 통해 User를 생성해보겠습니다.
# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from .validators import UnicodeUsernameValidator
# Create your models here.
class User(AbstractUser):
username_validator = UnicodeUsernameValidator()
username = models.CharField(
("username"),
max_length=150,
unique=True,
help_text=(
"Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only. 그리고 ~도 사용 가능합니다."
),
validators=[username_validator],
error_messages={
"unique": ("A user with that username already exists."),
},
)
User클래스에 AbstractUser를 상속받고
username부분만 기존과 다르게 수정했습니다.
help_text끝부분에 ~도 사용이 가능하다고 설명을 추가했고
해당 로직이 가능하게 하기 위해 UnicodeUsernameValidator도 수정했습니다.
from django.core import validators
from django.utils.deconstruct import deconstructible
@deconstructible
class UnicodeUsernameValidator(validators.RegexValidator):
regex = r"^[\w.~@+-]+\Z"
message = (
"Enter a valid username. This value may contain only letters, "
"numbers, and @/./+/-/_/~ characters. 후후후 수정해보기"
)
flags = 0
UnicodeUsernameValidator클래스의 정규표현식 부분을 보면 중간에 ~가 추가된 걸 확인할 수 있습니다.
message에도 후후후 수정해보기라는 글을 추가했습니다.
(해당 메시지는 validator를 통과하지 못했을 시 나타나는 메시지입니다.)
이제 실제로 서버를 켜고 admin페이지에 가서 User 생성 페이지에 가보면
Username밑에 나타나는 메시지가 필자가 수정한 메시지로 바뀐 걸 확인할 수 있습니다.
수정한 Validator실패 메시지를 확인하기 위해
일부러 username에 사용할 수 없는 &를 넣어서 생성해보았습니다.
&를 넣으니 Username입력칸 위에 빨간색 글씨로 UnicodeUsernameValidator클래스에서
수정한 내용이 나타나는 걸 확인할 수 있습니다.
(후후후 수정해보기는 입력실패와는 어울리지 않는 메시지입니다.)
(대충 변경된 모습을 보여주기 위해서 추가한 메시지라 😅 ;;)
마지막으로 확인해볼 부분은
regex = r"^[\w.@+-]+\Z" --> regex = r"^[\w.~@+-]+\Z"
정규표현식에 ~를 추가했기 때문에
~가 들어간 username도 생성가능한지 확인해 봐야 합니다.
이전과 다르게 username에 ~도 사용이 된다는 걸 확인할 수 있습니다.
이렇게 기존에 제공되는 User모델의 코드를 어느 정도 수정하면
User모델을 커스터마이징 할 수 있습니다.
(필자는 AbstractUser를 통해 커스터마이징 했지만 다른 방법도 가능합니다. -> 이에 대한 내용은 다음 포스팅에서)
사실 Django에서 기본적으로 제공되는 User모델은
username = models.CharField(
...
)
first_name = models.CharField(_("first name"), max_length=150, blank=True)
last_name = models.CharField(_("last name"), max_length=150, blank=True)
email = models.EmailField(_("email address"), blank=True)
is_staff = models.BooleanField(
...
)
is_active = models.BooleanField(
...
),
)
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
이렇게 7개의 필드밖에 없습니다.
하지만 웹사이트를 만들다 보면
위 코드에는 email이 blank=True로 필수 입력사항이 아니지만
우리 사이트에는 필수 입력사항일 수도 있고
위 필드 말고도 전화번호라던지 주소 같은 추가적인 회원 데이터가 필요할 수 있습니다.
이럴 때는 위에서 봤듯이 User모델을 커스터마이징 해야 합니다.
이번 포스팅에서는 User모델에 있는 Validator를 커스터마이징 해서
검증 로직을 바꿔보았습니다.
하지만 사실상 거의 맛만 본 수준이기 때문에
User모델을 자세히 커스터마이징 하는 것은 다음 포스팅에서 설명하겠습니다.
'Back-End > Django' 카테고리의 다른 글
Django(DRF) CORS 정책 해결 (0) | 2023.03.06 |
---|---|
[Django] DRF Filtering APIView로 적용해보기 (0) | 2023.01.02 |
[Django] DRF 페이지네이션, APIView에서의 적용법 (0) | 2022.12.26 |
[Django] UserAdmin으로 Admin페이지 커스터마이징 해보기 (0) | 2022.12.12 |
[Django] AbstractUser로 User모델 커스터마이징 해보기 (0) | 2022.12.07 |