Django를 처음 배울 때 우리는 django-admin startproject myproject 명령어로 시작합니다.
하지만 프로젝트 규모가 커지고 앱(App)이 하나둘 늘어나기 시작하면, 루트 디렉토리는 금세 난장판이 됩니다.
- settings.py 하나에 개발/배포 설정이 뒤섞여 있고 (DEBUG = True 껐다 켰다 해야함..)
- 루트 폴더에는 users, products, orders 등 앱 폴더들이 나뒹굴고...
- 프로젝트 설정 폴더 이름은 프로젝트 이름과 같아서(myproject/myproject) 헷갈립니다.
이번 프로젝트(KCAreportForShopping)를 진행하면서, 유지보수성과 확장성을 고려해 "프로덕션 레벨의 디렉토리 구조"로 리팩토링한 과정을 공유합니다.
1. Before vs After: 무엇이 바뀌었나?
가장 먼저 구조의 변화를 한눈에 보겠습니다.
❌ 기존 구조 (Default)
config와 app이 같은 레벨에 섞여 있어, 어디가 설정이고 어디가 기능인지 한눈에 파악하기 어렵습니다.
myproject/
├── manage.py
├── myproject/ # 설정 폴더 이름이 프로젝트랑 같음 (헷갈림)
│ ├── settings.py # 설정 파일이 하나뿐임
│ └── urls.py
├── users/ # 앱들이 루트에 산재함
├── products/
└── ...
✅ 변경된 구조 (Refactored)
설정(Config)과 기능(Apps)을 물리적으로 격리했습니다.
backend/
├── manage.py
├── config/ # [1] 이름 변경: myproject -> config
│ ├── settings/ # [2] 설정 분리: 파일 하나 -> 폴더 패키지
│ │ ├── base.py # 공통 설정
│ │ ├── local.py # 개발용
│ │ └── prod.py # 배포용
│ └── urls.py
└── apps/ # [3] 앱 격리: 모든 앱을 apps 폴더로 이동
├── users/
├── products/
└── core/
2. 리팩토링 핵심 포인트 3가지
Point 1. 설정 폴더 이름 명확화 (backend → config)
startproject로 생성된 내부 폴더의 이름을 config로 변경했습니다.
- 이유: 이 폴더가 "프로젝트 전체의 설정(Configuration)"을 담당한다는 역할을 이름만 보고도 알 수 있게 하기 위해서입니다.
- 효과: backend/backend/settings.py 같은 이상한 경로 대신 backend/config/settings/...로 직관적인 경로를 갖게 됩니다.
Point 2. settings.py 쪼개기 (환경 분리)
하나의 settings.py에 if DEBUG: 문을 써가며 개발/배포 설정을 섞어 쓰는 것은 위험합니다. 실수로 배포 서버에서 디버그 모드를 켤 수도 있습니다.
따라서 저는 settings를 패키지(폴더)로 만들고 역할을 나눴습니다.
- base.py: 모든 환경 공통 설정 (Installed Apps, Middleware 등)
- local.py: 로컬 개발용 (DEBUG = True, SQLite 사용)
- prod.py: 실서버 배포용 (DEBUG = False, PostgreSQL, S3, 보안 설정)
📝 적용 코드 (settings/local.py 예시)
from .base import * # base의 모든 설정을 가져옴
DEBUG = True
ALLOWED_HOSTS = ["*"]
# 로컬에서는 가벼운 SQLite 사용
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
Point 3. apps 폴더로 기능 격리 (Namespace 관리)
앱이 10개, 20개가 되면 루트 디렉토리가 너무 복잡해집니다.
모든 앱을 apps/라는 폴더 안에 몰아넣었습니다. 하지만 이렇게 물리적으로 옮기면 Django가 앱을 찾지 못하는 문제가 발생합니다.
💡 해결책: sys.path 추가 Django가 apps 폴더 안을 검색할 수 있도록 base.py에 경로를 추가해 줬습니다.
# config/settings/base.py
import sys
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# [핵심] apps 폴더를 파이썬 조회 경로에 추가!
sys.path.append(str(BASE_DIR / 'apps'))
이제 INSTALLED_APPS에 apps.users라고 쓸 필요 없이, 예전처럼 users라고만 써도 Django가 알아서 찾아냅니다.
3. 트러블 슈팅: "모듈을 찾을 수 없어요!" 🚨
구조를 바꾼 뒤 runserver를 했더니 ModuleNotFoundError가 발생했습니다.
원인은 manage.py와 wsgi.py가 여전히 옛날 주소를 가리키고 있었기 때문입니다.
이 파일들을 열어 경로를 수정해 주어야 리팩토링이 완료됩니다.
# manage.py
def main():
# [수정 전] 'backend.settings'
# [수정 후] 'config.settings.local' (설정 폴더명과 파일 위치 변경 반영)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')
(wsgi.py와 asgi.py도 동일하게 config.settings.prod 등으로 수정해 줘야 합니다.)
4. 결론: 구조가 좋으면 개발이 즐겁다
처음엔 "굳이 폴더 몇 개 옮기는 게 중요한가?" 싶었지만, 구조를 정리하고 나니 다음과 같은 장점이 있었습니다.
- 가독성: 프로젝트를 처음 보는 사람도 어디가 설정이고, 어디가 비즈니스 로직인지 바로 알 수 있습니다.
- 안정성: 로컬 설정과 배포 설정이 물리적으로 분리되어, 배포 사고를 방지할 수 있습니다.
- 확장성: 앱이 아무리 늘어나도 apps 폴더 안에 정리되므로 루트 디렉토리가 깨끗합니다.
Django 프로젝트를 새로 시작한다면, startproject 직후에 이 구조로 리팩토링하고 시작하는 것을 강력 추천합니다.
'와이즈픽' 카테고리의 다른 글
| [wise-pick 개발] Next.js SEO 최적화로 Lighthouse 100점 달성기 (0) | 2025.12.25 |
|---|---|
| [📚서비스 개발기] [Q&A] 1인 개발과 팀 개발의 플로우의 차이와 생산성 극대화 전략 문답 모음 (0) | 2025.12.07 |
| [📚서비스 개발기] "장고의 wsgi와 asgi 기술의 차이" (1) | 2025.11.30 |