본문 바로가기
Django

첫 번째 Django 앱 만들기 (Part 2: Models and the admin site)

by AlbertIm 2024. 8. 10.

시작

Part1을 이어서 간단한 설문조사(Polls) 앱을 만드는 과정을 통해 Django의 Models와 admin site를 알아보려고 합니다. 본 포스트에서는 macOS와 IntelliJ IDEA Ultimate을 사용합니다.

본문

settings.py 파일

이 파일은 모듈 변수를 사용하여 Django 설정을 정의하는 보편적인 설정 파일입니다.

BASE_DIR 설정

이 변수는 프로젝트 내에서 경로를 구성하는 데 사용됩니다. 예를 들어 BASE_DIR / 'subdir'와 같이 사용합니다. 아래 코드는 현재 파일의 상위 폴더의 상위 폴더를 의미합니다. ( settings.py -> mysite -> mysite)

 

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY 설정

이 설정은 세션, 쿠키, 비밀번호 해싱 등에 보안에 사용되는 키를 정의합니다. 배포 시 이 값을 외부에 노출해서는 안됩니다.

 

SECRET_KEY = 'django-insecure-#g$#&z(1*a!3br)o1_=55bsj+ihbpa!h_60o(q$i6rbw)ei8@z'

DEBUG 모드 설정

DEBUGTrue로 설정하면 Django는 상세한 오류 메시지와 디버깅 정보를 제공합니다. False로 설정하면 오류가 발생했을 때 자세한 정보가 제공되지 않고 설정된 오류 페이지가 표시됩니다. 따라서 개발 시에만 True로 설정합니다.

 

DEBUG = True

ALLOWED_HOSTS 설정

이 설정은 Django 서버가 요청을 허용할 호스트 이름을 명시하는 리스트입니다.

 

# 기본 설정
ALLOWED_HOSTS = []

# 예시 설정
ALLOWED_HOSTS = ['example.com', 'www.example.com', 'sub.example.com']

INSTALLED_APPS 설정

이 설정은 현재 Django 인스턴스에서 활성화된 모든 Django 앱들의 이름이 담고 있습니다. 앱들은 다수의 프로젝트에서 사용될 수 있으며 다른 프로젝트에서 쉽게 사용될 수 있도록 패키징하여 배포할 수도 있습니다.

기본적으로 Django와 함께 제공되는 앱들은 다음과 같습니다.

 

INSTALLED_APPS = [  
    'django.contrib.admin',  # 관리자 사이트를 만드는데 필요한 앱  
    'django.contrib.auth',  # 인증 시스템을 만드는데 필요한 앱  
    'django.contrib.contenttypes',  # 컨텐츠 타입 시스템을 만드는데 필요한 앱  
    'django.contrib.sessions',  # 세션 관리 시스템을 만드는데 필요한 앱  
    'django.contrib.messages',  # 메시지 프레임워크를 만드는데 필요한 앱  
    'django.contrib.staticfiles',  # 정적 파일 관리 시스템을 만드는데 필요한 앱  
]

MIDDLEWARE 설정

미들웨어는 Django의 요청과 응답의 처리 과정에 개입하는 프레임워크입니다. 이 설정에서는 Django에서 사용할 미들웨어 프레임워크 리스트를 설정할 수 있습니다.

 

MIDDLEWARE = [  
    'django.middleware.security.SecurityMiddleware',  # 보안 관련 기능을 제공하는 미들웨어  
    'django.contrib.sessions.middleware.SessionMiddleware',  # 세션 관리 기능을 제공하는 미들웨어  
    'django.middleware.common.CommonMiddleware',  # 여러가지 장고 기능을 제공하는 미들웨어  
    'django.middleware.csrf.CsrfViewMiddleware',  # CSRF 보호 기능을 제공하는 미들웨어  
    'django.contrib.auth.middleware.AuthenticationMiddleware',  # 사용자 인증 기능을 제공하는 미들웨어  
    'django.contrib.messages.middleware.MessageMiddleware',  # 메시지 프레임워크 기능을 제공하는 미들웨어  
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  # 클릭재킹 공격을 방어하는 미들웨어  
]

ROOT_URLCONF 설정

이 설정은 Django가 루트 URL 설정 파일의 위치를 정의합니다.

 

ROOT_URLCONF = 'mysite.urls'

TEMPLATES 설정

이 설정은 Django와 함께 사용되는 모든 템플릿 엔진에 대한 설정을 포함됩니다.

  • BACKEND: 사용할 템플릿 백엔드를 지정합니다. 기본 제공 템플릿 백엔드는 다음과 같습니다.
    • django.template.backends.django.DjangoTemplates
    • django.template.backends.jinja2.Jinja2
      DjangoTemplates은 Django과 통합이 잘되어 있고 Jinja2는 더 복잡한 템플릿 기능을 지원합니다.
  • DIRS: 템플릿 엔진이 템플릿 소스 파일을 찾아야 하는 디렉터리의 순서를 지정합니다.
  • APP_DIRS: 엔진이 설치된 애플리케이션 내에서 템플릿 소스 파일을 찾아야 하는지 여부를 결정합니다.
  • OPTIONS: 템플릿 백엔드에 전달할 추가 매개변수를 설정합니다.

 

TEMPLATES = [  
    {        
        'BACKEND': 'django.template.backends.django.DjangoTemplates',  
        'DIRS': [BASE_DIR / 'templates']  
        ,  
        'APP_DIRS': True,  
        'OPTIONS': {  
            'context_processors': [  
                'django.template.context_processors.debug',  
                'django.template.context_processors.request',  
                'django.contrib.auth.context_processors.auth',  
                'django.contrib.messages.context_processors.messages',  
            ],  
        },  
    },  
]

 

WSGI_APPLICATION 설정

WSGI 애플리케이션 객체의 전체 Python 경로로 Django의 내장 서버(예: runserver)가 사용할 경로를 지정합니다.

 

WSGI_APPLICATION = 'mysite.wsgi.application'

DATABASES 설정

이 설정은 사용할 데이터베이스를 정의합니다. 기본적으로 Django는 SQLite를 데이터베이스로 사용합니다.

 

DATABASES = {  
    'default': {  
        'ENGINE': 'django.db.backends.sqlite3',  
        'NAME': BASE_DIR / 'db.sqlite3',  
    }  
}

 

Django는 공식적으로 다음 데이터베이스를 지원합니다:

  • PostgreSQL
  • MariaDB
  • MySQL
  • Oracle
  • SQLite

PostgresSQL 데이터베이스 연결 설정 예시:

 

# settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "OPTIONS": {
            "service": "my_service",
            "passfile": ".my_pgpass",
        },
    }
}
# .pg_service.conf
[my_service]
host=localhost
user=USER
dbname=NAME
port=5432
# .my_pgpass
localhost:5432:NAME:USER:PASSWORD

AUTH_PASSWORD_VALIDATORS 설정

이 설정은 사용자 비밀번호의 강도를 확인하는 데 사용되는 유효성 validator들을 정의합니다.

 

AUTH_PASSWORD_VALIDATORS = [  
    {        # 사용자 이름과 유사한 비밀번호를 사용하지 못하도록 검사합니다.  
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',  
    },  
    {  
        # 비밀번호의 최소 길이를 설정하여 비밀번호가 충분히 긴지 검사합니다.  
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',  
    },  
    {  
        # 일반적으로 사용되는 비밀번호를 사용하지 못하도록 검사합니다.  
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',  
    },  
    {  
        # 비밀번호에 숫자가 포함되어 있는지 검사합니다.  
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',  
    },  
]

LANGUAGE_CODE 설정

LANGUAGE_CODE는 세 가지 목적을 위해 사용합니다.

  1. 로케일 미들웨어가 사용되지 않는 경우 모든 사용자에게 제공할 기본 언어를 결정합니다.
  2. 로케일 미들웨어가 활성화된 경우 사용자의 선호 언어를 결정할 수 없거나 웹사이트에서 지원하지 않는 경우에 대비하여 기본 언어를 제공합니다. 또한 사용자의 선호 언어에 대한 번역이 존재할지 않을 때 기본 언어를 제공합니다.
  3. unlocalize 필터나 {% localize off %} 태그를 통해 현지화가 명시적으로 비활성화된 경우 대신 적용될 기본 언어를 제공합니다.
LANGUAGE_CODE = 'ko-kr'

TIME_ZONE 설정

모든 뷰와 모델에서 사용하는 시간대를 작성합니다.

 

TIME_ZONE = 'Asia/Seoul'

USE_I18N 설정

Django의 번역 시스템을 활성화할지 여부를 지정합니다.

 

USE_I18N = True

USE_TZ 설정

날짜/시간이 기본적으로 시간대를 인식할지 여부를 지정합니다.

  • TRUE: Django는 내부적으로 시간대 인식 날짜/시간을 사용합니다. 즉 모든 날짜와 시간 데이터는 기본적으로 UTC로 저장디고 사용자에게 표시할 때만 사용자의 로컬 시간대로 변환됩니다. 사용자의 로컬 시간대에 맞게 날짜와 시간을 변환하여 표시할 수 있습니다.
  • FALSE: Django는 ISO 8601 형식의 문자열을 구문 분석할 때를 제외하고 현지 시간의 날짜/시간을 사용합니다. 즉 날짜와 시간 데이터는 현지 시간으로 저장되고 처리됩니다. 사용자가 여러 시간대에 걸쳐 접근하는 경우, 날짜와 시간의 일관성이 없을 수 있습니다.
USE_TZ = True

STATIC_URL 설정

이 설정은 정적 파일을 참조할 때 사용하는 기본 URL 경로를 정의합니다. 예를 들어 STATIC_URL/static/으로 설정된 경우 템플릿에서 {% static 'css/style.css' %}/static/css/style.css로 변환됩니다.

 

STATIC_URL = 'static/'

DEFAULT_AUTO_FIELD 설정

Primary_key=True로 설정된 필드가 없는 모델에 사용할 기본 키 필드 유형을 지정합니다. 즉 자동 생성 기본 키(PK)가 필요한 모델의 기본 키 생성 방식을 설정합니다.

 

# 기본 기본 키 필드 유형입니다. BigAutoField는 AutoField의 64비트 버전입니다.  
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

데이터베이스 설치

migrate 명령을 실행하기 전에 기본적으로 사용하는 SQlite 데이터베이스의 상태를 확인해 보겠습니다.

migrate 명령을 실행하면 INSTALLED_APPS의 설정을 탐색하여 mysite/settings.py의 데이터베이스 설정과 APP에 포함된 database migrations에 따라 필요한 데이터베이스 테이블을 생성됩니다.

 

python manage.py migrate

 

migrate 실행 후 SQlite 테이블(sqlite):

  • auth_group: 사용자 그룹을 정의하는 테이블
  • auth_group_permissions: 사용자 그룹에 대한 권한을 정의하는 테이블
  • auth_permission: 권한을 정의하는 테이블
  • auth_user: 사용자 정보를 저장하는 테이블
  • auth_user_groups: 사용자가 속한 그룹을 정의하는 테이블
  • auth_user_user_permissions: 사용자에게 부여된 권한을 정의하는 테이블
  • django_admin_log: Django 관리자 인터페이스의 로그를 저장하는 테이블
  • django_content_type: 콘텐츠 유형을 정의하는 테이블 (예: 모델)
  • django_migrations: 데이터베이스 마이그레이션 기록을 저장하는 테이블
  • django_session: 사용자 세션 정보를 저장하는 테이블

모델 만들기

모델은 데이터를 관리하는 하나의 정보 소스입니다. 각 모델은 저장할 데이터의 필수 필드와 동작을 정의합니다. 일반적으로 각각의 모델은 하나의 데이터베이스 테이블에 매핑됩니다.

 

  • 각 모델은 django.db.models.Model의 하위 Python 클래스입니다.
  • 모델의 각 속성 데이터베이스의 필드를 표현합니다.
  • Django는 모델에 대해 자동으로 생성된 데이터베이스 액세스 API를 제공합니다.

polls/models.py 파일을 다음과 같이 수정합니다.

 

  • CharField문자(character) 필드를 표현합니다.
  • DataTimeField날짜와 시간(datetime) 필드를 표현합니다.
  • ForeignKey는 Choice와 Question의 다대일(many-to-one) 관계를 표현합니다.
  • IntegerField정수(interger) 필드를 표현합니다.
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

모델 활성화

Django는 모델을 가지고 다음과 같은 작업을 수행할 수 있습니다.

  • 이 앱을 위한 데이터베이스 스키마 생성합니다.(CREATE TABLE 문 등)
  • 모델 객체에 접근하기 위한 Python 데이터베이스 접근 API를 생성합니다.

먼저 현재 프로젝트에 polls 앱을 설치해야 합니다. mysite/settings.pyINSTALLED_APPSpools.apps.PollsConfig를 추가합니다. Config 클래스는 Django 앱의 상세 설정을 정의하는 클래스입니다. 이를 추가하면 앱의 모든 설정이 적용됩니다.

 

INSTALLED_APPS = [
    "polls.apps.PollsConfig",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]

 

Migration은 Django가 모델의 변경사항디스크저장하는 방법입니다. 다음과 같은 명령어를 사용합니다.

 

python manage.py makemigrations polls

 

 

polls/migrations/0001_initial.py에 Migration 정보를 저장됩니다.

 

sqlmigrate 명령을 사용하면 migration 이름을 인수로 받아 실행하는 SQL 문을 보여줍니다.

 

python manage.py sqlmigrate polls 0001

 

check 명령을 통해 migration을 수행하거나 데이터베이스를 건드리지 않고도 프로젝트의 문제를 확인할 수 있습니다.

 

python manage.py check

 

이제 migrate 명령을 사용하여 아직 적용하지 않은 migration을 모두 수집하고 이를 실행하여 변경 사항들과 데이터베이스의 스키마 동기화할 수 있습니다.

 

python manage.py migrate

 

모델의 변경을 위한 3 단계

  1. 모델을 변경합니다.
  2. makemigrations 명령을 사용하여 이 변경 사항에 대한 마이그레이션을 만듭니다.
  3. migrate 명령을 사용하여 변경 사항을 데이터베이스에 적용합니다.

API 사용

Python shell에서 Django API를 자유롭게 사용할 수 있습니다.

 

python manage.py shell

 

명령어 사용에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

Django 관리자 소개

관리자 생성하기

다음 명령어를 실행하면 관리 사이트에 로그인할 수 있는 슈퍼 사용자를 생성할 수 있습니다.

 

python manage.py createsuperuser

 

개발 서버 시작

Django 관리자 사이트기본으로 활성화되어 있습니다. 개발 서버에서 확인할 수 있습니다.

개발 서버를 실행하기 위해 다음 명령어를 사용합니다.

 

python manage.py runserver

 

관리자 URL 주소는 mysite/urls.py 파일에서 확인할 수 있습니다. 관리자 기본 URL 주소가 /admin/입니다.

 

http://127.0.0.1:8000/admin/에 접속하면 로그인 화면이 나타납니다. LANGUAGE_CODE를 ko-kr로 설정했으므로 Django의 번역 기능이 활성화되어 화면이 한글로 표시됩니다.

 

 

관리자 사이트 들어가기

생성한 슈퍼 사용자 계정으로 로그인할 수 있습니다. 다음과 같은 Django 관리자 페이지가 보입니다.

 

 

관리 사이트에서 poll app을 변경가능하도록 만들기

polls/admin.py파일에 QuestionChoice 모델을 등록합니다.

 

from django.contrib import admin  

from .models import Choice, Question  

admin.site.register(Question)  
admin.site.register(Choice)

관리 사이트에서 POOLS 앱을 관리하기

관리 사이트의 메인 화면입니다. ChoicesQuestions모델이 추가된 것을 확인할 수 있습니다.

 

 

모델을 추가할 수 있습니다.

 

 

모델의 __str__ 를 설정하지 않으면 Question object와 같은 기본 표현이 표시됩니다.

 

 

모델에 __str__ 메서드를 구현하여 더 읽기 쉬운 표현을 제공할 수 있습니다.

 

from django.db import models  


class Question(models.Model):  
    question_text = models.CharField(max_length=200)  
    pub_date = models.DateTimeField("date published")  

    def __str__(self):  
        return self.question_text  


class Choice(models.Model):  
    question = models.ForeignKey(Question, on_delete=models.CASCADE)  
    choice_text = models.CharField(max_length=200)  
    votes = models.IntegerField(default=0)  

    def __str__(self):  
        return self.choice_text

 

 

위에서 소개한 추가 외에도 편집, 저장 및 편집 계속, 저장 및 다른 이름으로 추가, 삭제 등 다양한 기능을 지원합니다.

마무리

Part2를 통해 settings.py, 데이터베이스, 모델 그리고 Django 관리 사이트의 기본 사용법에 대해 간단히 정리해 봤습니다. Django의 기본 설정과 데이터베이스 설정을 비롯해 모델 정의와 관리 사이트 활용법까지 살펴보면서 Django의 강력한 내장 기능과 확장성을 체감할 수 있었습니다. Part3이 기대됩니다.

참고자료

댓글