2021. 5. 15. 20:45ㆍDev/Django
#Django의 User Model과 Customizing의 필요성
Django의 장점 중 하나는, 개발자가 유저 모델을 직접 만들 필요가 없다는 것이다.
대부분의 서비스는 Login 및 회원 인증이 필요하고, 이를 구현하기 위해 위해 개발자는 라이브러리 및 프레임워크를 이용하여 User 인증 모듈 및 해당 Model을 만들어야 한다.
그러나 Django는 기본적으로 제공하는 User Model이 있기 때문에, 간단한 구조의 User DB Table이 요구되는 경우는 개발자가 굳이 User DB Table을 설계하지 않더라도 Django의 기본 모델을 사용할 수 있기에 개발하는데 시간이 단축 될 수 있다.
하지만 몇몇 경우에는 직접 User Model을 설계해야 할 필요가 있다. 가령 꼭 필요한 field가 있다던지, 혹은 유저를 인증하기 위한 수단이 id가 아닌 email이라던지..(Django의 User Model은 username이라는 필드가 고유키, 즉 로그인할 때 사용하는 id정도가 되겠다)
또한 Django에서도 새로운 프로젝트를 진행할 경우는, Django에서 제공하는 User Model을 사용할지라도, 맞춤 사용자 모델을 사용할 것을 강력하게 권고하고 있다(그 이유는 Django의 User 모델을 사용하는데, 중간에 User Model의 필드 등을 교체해야 할 경우가 생긴다면 굉장히 번거롭고 힘든 일이 될 것이기에, 변화에 대응할 수 있도록 하는 것이다.)
#Django의 User Model Field
Custom하기 전에, 기본 User Model의 필드는 여러가지가 있는데, 이 중 중요하다고 생각되는 것만 적어보겠다.
- username
-> 필수 사항으로, 쉽게 말해 ID라고 생각하면 된다.
- password
-> 필수 사항으로, 말 그대로 비밀번호인데 Django는 이 password 값을 저장할 때 암호화 및 해쉬화를 거쳐 저장한다.
- is_admin
-> Superuser(관리자)인지 판단한다. Superuser란 DB에 접근해서 직접 DB 값을 수정 및 추가, 삭제할 수 있다.
- is_active
-> 해당 User가 활성화 상태인지 판단한다. 즉 유효한 계정인지 판단한다.
#Django User Model Custom하기
먼저 Django의 User Model은 username(string 값)과 password로 로그인을 하는데, email이라는 필드를 만들어서 email 형식으로 로그인을 할 수 있도록 하는 User Model을 만들어보자.
User Model을 커스텀 할 app을 만들어야 한다. Django 프로젝트의 디렉토리에 하나의 앱을 만들자. user라는 app을 만들어보자.
python3 manage.py startapp user
새로운 Model을 만들 것이므로, user/model.py에 가서 model을 만들자.
# Create your models here.
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.utils import timezone
class UserManager(BaseUserManager) :
def create_user(self, email, name, password = None) :
if not email :
raise ValueError("User must have an Email")
user = self.model(
email = self.normalize_email(email),
name = name
)
user.set_password(password)
user.save(using = self._db)
return user
def create_superuser(self, email, name, password = None) :
superuser = self.create_user(email, name, password = password)
superuser.is_admin = True
superuser.save(using = self._db)
return superuser
class User(AbstractBaseUser) :
email = models.EmailField(unique = True)
name = models.CharField(max_length = 20)
is_active = models.BooleanField(default = True)
is_admin = models.BooleanField(default = False)
date_joined = models.DateTimeField(default = timezone.now)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [ 'name' ]
def __str__(self) :
return self.email
def has_perm(self, perm, obj = None) :
return True
def has_module_perms(self, app_label) :
return True
def is_staff(self) :
return self.is_admin
Line2의 BaseUserManager, AbstractBaseUser를 보자.
- BaseUserManager
Custom User를 생성하기 위해 관리하는 class가 필요하다. 이 class를 선언할 때, BaseUserManager를 상속하여 선언할 수 있다.
- AbstractBaseUser
Custom User는 기본적으로 Django의 기본 User Model의 틀을 따른다. 따라서 기본 User Model의 추상 클래스를 상속받는데, 이것이 AbstractBaseUser 클래스이다.
위와 같이 2개의 class를 만들었다. UserManager와 User 클래스이다.
- UserManager
두 개의 User를 만든다. 일반 user와 superuser를 만드는데, email로 로그인을 할 것이기 때문에, 반드시 email이 필요하며, superuser같은 경우는 관리자이기 때문에, is_admin 값을 True로 설정한다.
- User
필드는 아래와 같다.
- email : 로그인 할 때 필요한 email, email 형식이고 중복되는 값이 있을 수 없다.
- name : 사용자의 이름
- is_active : 활성화된 계정인지
- is_admin : superuser 계정인지(= 관리자인지)
- date_joined : 언제 계정이 만들어졌는지.
이후 중요한 값들이 있는데,
- USERNAME_FIELD
Django의 기본 User Model은 username이 ID이기 때문에 필수항목이다. 그러나 지금은 email이 필수항목이고 이것이 곧 사용자를 나타내기에 기존의 username 값을 email로 바꿔줘야 한다. 따라서 USERNAME_FIELD의 값을 수정하여 ID를 변경한다고 생각하면 된다.
- REQUIRED_FIELDS
말 그대로 계정을 만들 때 꼭 필요한 Field값들을 말하고, List형태이다. 이 값 안에는 USERNAME_FIELD의 값이 들어갈 수 없다. 들어가면 에러남
model을 만들었으니 이 model을 바탕으로 관리자 페이지에서 데이터를 수정할 수 있는 form을 만들어보자.
user/admin.py에서 아래의 코드를 입력한다.
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from .models import User
class UserCreationForm(forms.ModelForm) :
password1 = forms.CharField(label = 'Password', widget = forms.PasswordInput)
password2 = forms.CharField(label = 'Password Check', widget = forms.PasswordInput)
class Meta :
model = User
fields = ('email', 'name', 'password')
def clean_password2(self) :
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2 :
raise ValidationError("Password dosen't match")
return password2
def save(self, commit = True) :
user = super().save(commit = False)
user.set_password(self.cleaned_data['password1'])
if(commit) :
user.save()
return user
class UserChangeForm(forms.ModelForm) :
password = ReadOnlyPasswordHashField()
class Meta :
model = User
fields = ['email', 'name', 'is_active', 'is_admin']
def clean_password(self) :
return self.initial['password']
class UserAdmin(BaseUserAdmin) :
form = UserChangeForm
add_form = UserCreationForm
list_display = ('email', 'name', 'is_active', 'is_admin')
list_filter = ('is_admin', 'name')
add_fieldsets = (
(None, {'fields' : ('email', 'name', 'password1', 'password2')}),
)
fieldsets = (
('User', {'fields' : ('email', 'password')}),
('Personal Info', {'fields' : ('name', 'date_joined')}),
('Permissions', {'fields' : ('is_admin',)})
)
search_fields = ('email', 'name')
ordering = ('date_joined',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
# Register your models here.
form은 말 그대로 어떤 형태의 form을 만들지를 의미하고, 지금은 model을 관리하는 form을 만들 것이다.
총 3가지의 클래스를 생성한다.
- UserCreationForm : User를 생성하는 Form
- UserChangeForm : User의 정보를 변경하는 Model Form
- UserAdmin : 유저를 생성 및 관리
각각에 대한 자세한 설명은 코드를 보면 쉽게 이해할 수 있어서 넘어가고..
UserAdmin만 덧붙이자면 superuser로 로그인을 했을 경우 관리 페이지의 양식을 수정하는 클래스이고, 이 클래스를 admin에 등록해야 한다.
이후 이렇게 Custom한 모델을 기본 User Model로 변경해야 하기에, project 폴더의 settings.py로 가서 내용을 수정한다.
INSTALLED_APPS = [
'django.contrib.admin',
...
'user.apps.UserConfig'
]
...
AUTH_USER_MODEL = 'user.User'
...
INSTALLED_APPS의 값에 새로 만든 app을 추가한다.
이후 AUTH_USER_MODEL 필드를 추가하고, "app의 이름.모델" 형태의 값으로 수정한다.
superuser를 생성한 이후에,
python3 manage.py createsuperuser
Django Server를 실행한 후, 관리자 페이지('/ admin')으로 들어가보면 양식이 정상적으로 바뀐 것을 알 수 있다.
출처 : https://docs.djangoproject.com/ko/3.2/topics/auth/customizing/#substituting-a-custom-user-model
Django 인증 커스터마이징하기 | Django 문서 | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
'Dev > Django' 카테고리의 다른 글
Django REST Framework(DRF)로 회원가입/로그인/로그아웃 하기 (0) | 2021.05.17 |
---|---|
Django 시작하기 #2 - View, Template (0) | 2021.04.11 |
Django 시작하기 #1 - App, DBMS 설정 (0) | 2021.04.05 |
Django란? (0) | 2021.03.30 |