[Django] 프로젝트 환경 만들기 (2)
setup.cfg 파일 만들기
다양한 파이썬에서 사용되는 도구 파일 (setup-tools, Pytest, Flake8, isotta 등..)에 대해 표준화된 형식으로 구성 설정을 정의하는 방법을 제공한다.
ini 파일 형식이며, 주의할 점은 cfg파일이 .toml 파일, .ini 파일 등의 다른 구성 파일과 함께 일반적으로 루트 수준에 위치한다.
[flake8]
max-line-length = 120 # 최대 라인 길이
# 스타일과 품질을 확인할 때 제외할 파일
exclue = .tox,.git,*/migrations/*,*env*,*venv*,__pycache__,*/staticfiles/*,*mediafiles/*,node_modules
[isort]
line-length = 88
skip = venv/
multi_line_output = 3
skip_glob = **/migrations/*.py
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
이제 설정을 .py 파일로 분할할 수 있다.요구사항과 마찬가지로 설정을 py 파일로 분할하는 것이 좋다. 즉, 로컬이든 프로덕션이든 환경에 따라 설정을 분할하는 것이다. 하나의 매우 큰 settings.py 파일을 피하기 위함이다. 다양한 환경에 대비해 하나의 큰 settings.py 파일을 가지는 경우, 유지관리하는 팀에서 번거로울 수 있다.
이후 모듈 (src 내에 생성한 장고 프로젝트 폴더)에 settings 폴더를 만들고 안에 __init__.py, base.py, local.py,production.py 이름의 의 환경 변수 설정 파일을 만들어준다. 그럼다음 (src 내에 생성한 장고 프로젝트 폴더) 내에 기존에 있던 settings.py 안의 내용을 전체 복사하여 base.py에 붙여넣어주고 기존의 settings.py는 삭제한다.
base.py 수정하기
import 부분 확인
기존에 있던 Path 라이브러리 이외에, OS의 환경변수를 확인해서 환경변수를 우선 적용하기 위해 environ 라이브러리를 추가로 import 한다. Docker나 Kubernetes로 올릴 때, yaml 확장자 파일에서 환경변수를 정의하거나 환경변수를 읽어들일 수 있게 해준다. 코드 수정없이 외부에서 변수를 수정할 때 용이하다.
from pathlib import Path
import environ
env = environ.Env()
DIR 재설정
""" base.py before """
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
""" base.py after """
# Build paths inside the project like this: BASE_DIR / 'subdir'.
ROOT_DIR = Path(__file__).resolve().parent.parent.parent # src 폴더를 의미한다.
""" base.py 신규 추가 """
# 앱 디렉터리(core_apps) 생성. 프로젝트 앱이 존재하는 곳
APP_DIR = ROOT_DIR / "core_apps"
기존 SECRET_KEY, DEBUG, ALLOWED_HOST 이동 (base.py에서 local.py로)
""" 아래 구문 잘라내기 후 local.py 붙여넣기 """
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-rb33vd=j!8keuir++ug0#2*2ck$&&j-)2rxz91&dmj8_*6%da8"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
Debug 재수정
""" base.py before """
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
""" base.py after """
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool("DJANGO_DEBUG", False) # DJANGO_DEBUG 환경변수가 기본적으로 존재하지 않으면 디버그는 False가 된다.
INSTALLED_APPS 분리하기
INSTALLED_APPS 제거 후 DJANGO_APPS, THIRD_PARTY_APPS, LOCAL_APP로 분리한다. 기존의 INSTALLED_APPS는 DJANGO_APPS로 변수명을 변경하고, "django.contrib.sites"를 추가한다.
""" base.py before """
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
""" after.py before """
# Application definition
DJANGO_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.sites", # 개체와 기능을 특정 웹사이트에 연결하기 위한 후크인 프레임워크, Django 기반 사이트의 도메인 이름과 자세한 이름을 보관하는 장소
]
# requirements.txt에 추가한 패키지들
THIRD_PARTY_APPS = ["rest_framework", "django_filters", "django_countries", "phonenumber_field", "drf_yasg", "corsheaders"]
# 사용자가 만든 앱 (ROOT_DIR의 core_app 폴더 안에 있다.)
LOCAL_APPS = ["core_apps.profiles", "core_apps.common", "core_apps.users"]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
MIDDLEWARE 추가하기
""" base.py before """
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
""" base.py before """
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"corsheaders.middleware.CorsMiddleware", # CorsMiddleware 추가
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
DATABASE 변경하기
""" base.py before """
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
""" base.py before """
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
# sqlite3는 개발, 프로덕션에 적합하지 않음. 차후 변경
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": "mydatabase",
}
}
# docker로 데이터베이스를 사용할 때 사용하는 환경변수로 매우 높은 관련성 (일단은 db설치 전까지는 주석)
# DATABASES = {"default": env.db("DATABASE_URL")}
PASSWORD_HASHERS 설정하기
Django Documentation https://docs.djangoproject.com/en/5.0/topics/auth/passwords/#using-argon2-with-django
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
"django.contrib.auth.hashers.ScryptPasswordHasher",
]
TIME_ZONE 변경하기
TIME_ZONE = "UTC" # before
TIME_ZONE = "Asia/Seoul" # after
SITE_ID 설정하기
기본 사이트 ID인 고유식별자를 나타내는 설정. django.contrib.sites와 엮여져 있다. 다양한 설정, 데이터 또는 동작을 여러 웹사이트, 단일 Django 명령을 사용하는 도메인 연결할 수 있다. 각 사이트는 고유한 ID와 도메인 이름을 가진 사이트 개체로 표시된다. SITE_ID = 1을 설정하면 해당 사이트의 기본 사이트가 지정된다. 프로젝트는 하나고 ID가 1이어야 한다. 이는 사이트가 하나만 있거나 대체 사이트를 지정하려는 경우에 특히 유용하다. 여러 사이트에서 작업할 때 기본적으로 사용된다.
ADMIN_URL 설정하기
# 실제 프로덕션에서 쉽게 예측할 수 없도록 supersecret을 변형시킨다.
ADMIN_URL = "supersecret/"
STATIC_URL 변경하기
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
# before
STATIC_URL = "static/"
# after
STATIC_URL = "/staticfiles/"
STATIC_ROOT = str(ROOT_DIR / "staticfiles")
MEDIA_URL 설정하기
MEDIA_URL = "/mediafiles/"
MEDIA_ROOT = str(ROOT_DIR / "mediafiles")
CORS_URLS_REGEX 설정하기
우리가 설치한 Django 코스 헤더 미들웨어에서 사용되는 설정. 기본적으로 Django 프로젝트의 Cross-origin 리소스 공유 또는 CORS를 처리한다. 이 설정은 HTTP 응답에 헤더를 추가해야 하는 URL을 정의하는 정규식이다.
아래의 경우는 API 슬래시로 시작하는 모든 URL에 코스 헤더가 추가됨을 의미한다.
CORS_URLS_REGEX = r"^api/.*$"
local.py 수정하기
주석 제거하기
아래 주석구문을 제거한다.
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
패키지 import
Adding noqa, which is no quality assurance to line, tells the linter to ignore this line.
from .base import * #noqa
from .base import env
Secret Key 생성하기
Secrets 모듈은 파이썬 3.6 버전부터 표준 패키지가 되었다. 이 패키지는 암호화된 보안 난수 및 문자열을 생성한다.
아래 코드는 38 byte의 random url을 생성한다. 글자 길이는 51자이다.
$ python -c "import secrets; print(secrets.token_urlsafe(38))"
출력값으로 나온 문자열을 SECRET_KEY에 선언해준다.
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env(
"DJANGO_SECRET_KEY",
default="TaSphqOrhSmrwV-JBMMgDSKV3nhm3Jzn_cYZMc4jbLvP8zKsbKg",
)
ALLOWED_HOSTS 제거하기
# 아래 변수는 제거한다.
ALLOWED_HOSTS = []
CSRF_TRUSTED_ORIGINS 설정하기
CSRF_TRUSTED_ORIGINS는 사이트간 요청을 허용하는 도메인 목록이다. 차후 역방향 프록시로 Nginx를 서버의 도메인을 추가한다.
CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"]