본문 바로가기

Django

DRF(Django REST framework)로 API 서비스 만들기-2

기본 설정을 했으면 이제 유저 모델을 만들어야 한다

 

 

1. User 모델 커스컴

 

보통 서비스를 개발하게 되면 서비스마다 조금씩 다른 유저 모델을 생성한다. 장고에서 유저 모델에 컬럼을 추가하거나 수정하기 위해서는 유저 모델을 만들어서 커스텀 해줘야 하는 번거로움이 있다.

 

 

 

a) 먼저 유저 모델 생성을 위해 앱을 만든다

 

python manage.py startapp account

 

 

 

b) config/settgins.py에 앱 추가

 

...
INSTALLED_APPS = [
    ...
    'account',
]
...

 

 

 

c) 커스텀할 유저 모델 생성

 

account/models.py

 

from django.db import models
from django.contrib.auth.models import (BaseUserManager, AbstractBaseUser)
from django.utils.timezone import now

class UserManager(BaseUserManager):
    def create_user(self, email, custom_field, password=None):
        if not email:
            raise ValueError('Email cannot be null!')

        user = self.model(
            email=self.normalize_email(email),
            custom_field=custom_field
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(
            email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    class Meta:
        db_table = 'users'

    email = models.EmailField(verbose_name='email', max_length=254, unique=True)
    custom_field = models.CharField(max_length=254)
    is_active  = models.BooleanField(default=True)
    is_admin   = models.BooleanField(default=False)
    created_at = models.DateTimeField(default=now, editable=False)
    updated_at = models.DateTimeField(default=now)

    objects = UserManager()

    USERNAME_FIELD  = 'email'

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

 

여기서는 이메일을 로그인 아이디로 쓰고, 기본 모델에 custom_field를 추가했다. 본인이 원하는 필드를 추가하면 된다.

 

 

 

d) 관리자 페이지 등록을 위해 form을 생성

 

관리자 페이지에서 해당 모델을 관리하기 위해 폼을 생성한다.

 

account/forms.py

 

from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from .models import User


class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(
        label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'custom_field', 'updated_at')

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don'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', 'password', 'custom_field', 'updated_at', 'is_active', 'is_admin')

    def clean_password(self):
        return self.initial["password"]

 

 

 

 

e) 관리자 페이지를 위해 모델을 등록

 

account/admin.py

 

from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

from .forms import UserChangeForm, UserCreationForm
from .models import User


class UserAdmin(BaseUserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm

    list_display = ('email', 'custom_field', 'updated_at', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('custom_field', 'updated_at',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2', 'custom_field', 'updated_at')}
        ),
    )
    search_fields = ('email', 'custom_field',)
    ordering = ('email', 'custom_field',)
    filter_horizontal = ()


admin.site.register(User, UserAdmin)
admin.site.unregister(Group)

 

 

 

 

f) 셋팅 파일에 커스텀 유저 모델을 유저 모델로 사용한다고 설정

 

config/settings.py

 

.
.
.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account',
]

AUTH_USER_MODEL = 'account.User'

.
.
.

 

 

 

 

g) 이제 마이그레이션으로 모델을 생성하면 완료

 

python manage.py makemigrations
python manage.py migrate

 

 

 

 

h) 기타 명령어

 

관리자용 계정을 생성한다

python manage.py createsuperuser

 

 

실행시켜 테스트 해보자

 

python manage.py runserver

 

localhost:8000/admin 으로 접속이 되면 성공이다.

 

 

 

 

 

 

여기까지 따라왔다면 폴더 구조가 아래와 같다