본문 바로가기
와이즈픽

[📚서비스 개발기] Django 프로젝트 디렉토리 구조 바꾸기

by mangji12 2025. 11. 30.

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. 결론: 구조가 좋으면 개발이 즐겁다

처음엔 "굳이 폴더 몇 개 옮기는 게 중요한가?" 싶었지만, 구조를 정리하고 나니 다음과 같은 장점이 있었습니다.

  1. 가독성: 프로젝트를 처음 보는 사람도 어디가 설정이고, 어디가 비즈니스 로직인지 바로 알 수 있습니다.
  2. 안정성: 로컬 설정과 배포 설정이 물리적으로 분리되어, 배포 사고를 방지할 수 있습니다.
  3. 확장성: 앱이 아무리 늘어나도 apps 폴더 안에 정리되므로 루트 디렉토리가 깨끗합니다.

Django 프로젝트를 새로 시작한다면, startproject 직후에 이 구조로 리팩토링하고 시작하는 것을 강력 추천합니다.

반응형