라이브러리는 도서관 아닌가요

[Django 5] Django DB model (1) - 사용자(유저) 앱 생성 및 DB 연결 본문

Django/Django 프로젝트

[Django 5] Django DB model (1) - 사용자(유저) 앱 생성 및 DB 연결

veryhi 2021. 10. 7. 16:19

 

 

 

 

이번에는 사용자 계정을 담당하는 앱을 만들어보자.

 

 

 

우선 user를 담당하는 app을 생성하자.

 

하던대로 cmd 창을 오픈 후 프로젝트의 manage.py가 있는 경로로 들어가 아래의 명령어를 실행한다.

 

python manage.py startapp user

 

 

 

 

 

 

예쁘게 생성되었다.

 

그 다음엔 무엇을 해야할까?

 

 

 

 

 

testproject/testproject/settings.py로 가서

 

INSTALLED_APPS에 'user.apps.UserConfig'를 추가해주자.

 

 

 

 

 

 

 

다음은 user 앱에 urls.py을 추가. (직접 맹글어줘야 한다. 우리는 url을 앱 별로 나눠 관리할 것이므로.)

from django.urls import path
from . import views

app_name = 'user'

urlpatterns = [
]

app_name = 'user'이 전과 다르게 추가 되었는데

 

views.py에서 요긴하게(?) 사용할 수 있다.

 

물론 사용하지 않아도 크게 상관은 없다.

 

 

 

 

 

그리고 '127.0.0.1:8000' + 'user/' 와 같은 도메인 입력이 들어왔을 때, user 앱으로 연결될 수 있도록

 

아래와 같이 testproject/testproject/urls.py에 추가한다.

 

잠깐

 

처음부터 순서대로 진행했다면,

 

다소 바뀐 부분이 있다.

 

아래와 똑같이 변경해주자.

 

이제는 127.0.0.1:8000만 입력한다고 해서

 

기존의 '반갑습니다' 메인 페이지가 열리지 않을 것이다.

 

127.0.0.1:8000/main 을 입력해주어야 접속이 된다.

 

장고가 처음이더라도 어떤 흐름인지 약간은 감이 잡힌다.

 

여기까지 왔다면 user app도 큰 얼개는 다 짠 것과 같다.

 

이제 db 모델을 관리하는 models.py를 다루어보자.

 

우리는 장고에서 기본적으로 제공해주는 model custom 방식인

 

AbstractBaseUser, BaseUserManager를 사용할 것이다.

 

 

 

 

 

< TMI >

AbstractBaseUser 모델을 상속한 사용자 커스텀 모델을 생성하면,

 

로그인 아이디로 'E-mail 주소'를 사용하거나,

 

Django 로그인 절차가 아닌 다른 인증 절차를 '직접 구현'할 수 있다.

 

단점은 서비스가 되고 있는 프로젝트의 경우, 모델을 변경하는 것이 많이 어려워진다는 점이다.

 

BaseUserManager는 User를 생성할 때 도움을 주는 클래스이다. 모델을 관리한다고 보면 된다.

 

모든 장고의 model들은 이러한 Manager를 통해, QuerySet을 받는다.

 

DB에서 query를 처리할 때, 이 Manager를 거쳐야 한다. 

 

 

 

 

 

자 다시 models.py로 돌아와서 아래와 같이 코드를 추가해주자. (당연히 위치는 testproject/user/models.py이다.)

 

혹시 추가/변경하고픈 항목이 있을 경우 해도 된다.

 

model 양식을 지켜서. 긴 타이핑에 손이 떨려온다.

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from .user_level import *

# Create your models here.
class UserManager(BaseUserManager):
    def create_user(self, userid, password, username, email, auth, **extra_fields):
        user = self.model(
            userid=userid,
            username=username,
            email=email,
            auth=auth,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, userid, password, username=None, email=None, auth=None):
        user = self.create_user(userid, password, username, email, auth)
        user.is_superuser = True
        user.is_staff = True
        user.is_admin = True
        user.is_active = True
        user.level = 0
        user.save(using=self._db)
        return user

class User(AbstractBaseUser, PermissionsMixin):
    objects = UserManager()

    userid = models.CharField(max_length=25, verbose_name="ID", unique=True)
    password = models.CharField(max_length=256, verbose_name="PW")
    email = models.EmailField(max_length=128, verbose_name="email", null=True, unique=True)
    username = models.CharField(max_length=70, verbose_name="username", null=True)
    level = models.CharField(choices=USER_LEVELS, max_length=18, verbose_name="level", default=3)
    auth = models.CharField(max_length=10, verbose_name="auth", null=True)
    date_joined = models.DateTimeField(auto_now_add=True, verbose_name='date_joined', null=True, blank=True)

    is_active = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = 'userid'
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return self.userid

    class Meta:
        db_table = "user"
        verbose_name = "user"
        verbose_name_plural = "user"

 

BaseUserManager를 상속받는 UserManager 클래스와

 

AbstractBaseUser를 상속받는 User 클래스를 생성했다.

 

웬만한 내용은 차근차근 살펴보면 직관적으로 이해할 수 있을 것이다.

 

지금은 어렵게 생각말자.

 

 

 

 

 

작성 완료했다면, 아마도 저기 위 from .user_level import * 부분에 빨간 불이 들어올 것이다.

 

왜냐면 존재하지 않는 위치를 참조해서 무언가를 import 했으니까.

 

그럼 만들자.

 

 

 

 

 

testproject/user/ 에 user_level.py 를 생성한다. 생각보다 내용도 별 거 없다.

내용 그대로,

 

3은 Lv3을 갖는 외부 사용자 (인증 안됨)

2는 Lv2를 갖는 내부 사용자

1은 Lv1을 갖는 관리자

0은 Lv0을 갖는 개발자

 

레벨이 낮을수록 권한이 많이 부여되도록 해뒀다. (보통 게임은 올라갈수록 세지던데)

 

즉, 위의 models.py에서 추가한 부분과 매칭시켜보면,

(보라색으로 칠해놓았다.)

 

db의 컬럼에 권한을 부여할 수 있도록

 

user_level.py의 리스트를 가지고 오는 것이다.

 

default는 3이다.

 

 

 

 

 

다음은, settings.py에 아래의 내용을 추가해주자.

 

 

 

 

 

이제 superuser가 관리하는 admin 페이지를 위해 아래의 내용을 추가하자.

 

 

 

 

 

이제 user model 생성은 끝났다.

 

cmd 창을 열고,

 

manage.py가 있는 위치로 이동해서 아래의 명령어를 순서대로 때려넣자.

python manage.py makemigrations
python manage.py migrate

 

 

 

 

 

< TMI >

원래 원칙적으로 makemigrations 뒤에는 새로 추가한 앱 이름을 넣어야 한다.

 

예를 들면, python manage.py makemigrations user

 

하지만, 지금은 초기 작업이고 처음 마이그레이션을 한 것이니 크게 상관 없을 것이다.

 

무엇보다 앱 수가 적다.

 

이런 결과들이 뜨면 정상 !

우리가 만든 model을 db에 연동하고 초기화한 것이다.

 

 

 

 

 

그리고 저런 파일이 하나 자동으로 만들어질 것이다.

보다시피 자동으로 생성되는 저 파일은, 딱 보기에 건드리기 껄끄러워 보인다.

 

실제로 그렇다.

 

db에 마이그레이션을 한 이후에는 django의 db 모델에 새로운 attribute를 추가하는 것이 다소 복잡해진다.

 

initial 파일들이 복잡 기괴하게 꼬이기 시작한다. 그리고 db에 실제 저장된 컬럼 데이터들이 존재한다면 더욱 그렇다.

 

attribute(→ userid, password, email...)는 그렇지 않으니 주의하자.

 

 

 

 

 

마지막으로 결과를 눈으로 확인하기 위해 superuser를 실제로 생성한다.

 

아래의 명령어 입력하자.

python manage.py createsuperuser

 

 

 

 

 

그러면 아래와 같이 요청이 있을 것이다.

 

실제 계정을 생성하는 것이므로 입력하자.

 

참고로 비밀번호 입력 때에는 보안(?)을 위해서 겉으로는 아무것도 뜨지 않는다.

 

하지만 제대로 입력되고 있으므로 계속 입력하고 엔터.

 

정상 생성 후 python manage.py runserver로 서버를 실행시켜보자.

 

그리고 아래의 주소로 접근해보자.

127.0.0.1:8000/admin

 

 

 

 

 

계정 정보를 입력을 하고, 아래와 같이 뜨면 성공!

 

이제 페이지를 관리할 수 있는 superuser를 정상 생성했다.

 

 

 

 

사용자 user app 완료

 

 

Comments