[Django] settings.py 설정하기

2017-02-20

settings.py의 분리

스택오버플로우에서 누군가가 잘 설명해주었다.1

아래의 파일 구조처럼, 기존의 settings.py 의 위치에 settings 폴더를 만들고 그 안에 base.py, local.py, production.py 파일을 만든다.

project/
    app1/
    app2/
    project/
        __init__.py
        settings/
            __init__.py
            base.py
            local.py
            production.py
        urls.py
        views.py
        wsgi.py
    manage.py

base.py 에는 MEDIA_ROOTADMIN과 같은 공통된 부분, local.py에는 로컬 환경에서의 설정, production.py에는 배포 환경에서의 설정을 적어준다.

Example

예를 들면, debug_toolbar는 개발할 때 디버깅을 쉽게 할 수 있도록 도와주는 앱인데, 배포 환경에서는 포함되지 않아야 하므로, local.py 에만 추가시켜주면 된다.

settings/base.py
INSTALLED_APPS = (
    # common apps...
)
settings/local.py
from project.settings.base import *

DEBUG = True
INSTALLED_APPS += (
    'debug_toolbar', # and other apps for local development
)
settings/production.py
from project.settings.base import *

DEBUG = False
INSTALLED_APPS += (
    # other apps for production site
)

BASE_DIR 수정

setting 파일의 경로가 바뀌었기 때문에 BASE_DIR의 경로가 달라질 수도 있다. 나는 다음과 같이 바꿔주었다.

settings/base.py
# before
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# after
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

setting 파일 경로 수정

그리고 wsgi.pymanage.py 에 바뀐 setting 파일의 경로를 알려준다.

wsgi.py
...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
...
manage.py
...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
...

SECRET_KEY의 분리

secrets.json 파일에 SECRET_KEY 를 두고, secrets.json 파일을 .gitignore 에 포함시켜서 소스코드를 공유할 때 외부에 공개되지 않도록 한다. 만약 팀으로 개발하고 있다면, 개별적으로 secrets.json 파일을 전해주도록 하자.

.gitignore
...
secrets.json
...
secrets.json
{ 
    "SECRET_KEY": "your-secret-key",
}
settings/base.py2
import json

# Normally you should not import ANYTHING from Django directly
# into your settings, but ImproperlyConfigured is an exception.
from django.core.exceptions import ImproperlyConfigured

# JSON-based secrets module
with open(os.path.join(BASE_DIR, "secrets.json")) as f:
    data = json.loads(f.read())
    
# Use namedtuple so secrets becomes a static object.
# secrets is a static object so we don't risk corruption of secret data.
SecretsNamedTuple = namedtuple('SecretsNamedTuple', data.keys(), verbose=False)
secrets = SecretsNamedTuple(*[data[x] for x in data.keys()])

def get_secret(setting, secrets=secrets):
    """ Get the secret variable or return explicit exception """
    try:
        return getattr(secrets, setting)
    except KeyError:
        error_msg = "Set the {0} environment variable".format(setting)
        raise ImproperlyConfigured(error_msg)

SECRET_KEY = get_secret("SECRET_KEY")