파일 구조를 넘어 Django 아키텍처 이해하기
Source: Dev.to
왜 Django 구조가 주니어들을 혼란스럽게 하는가
대부분의 주니어들은 Django에 이렇게 접근합니다:
“프로젝트를 만들었고, 앱을 만들었습니다. 이제 로직을 어딘가에 넣으면 동작합니다.”
혼란이 발생하는 이유는 다음과 같습니다:
- 프로젝트와 앱의 구분이 개념적으로 명확하지 않기 때문입니다.
- MTV 패턴이 피상적으로 소개됩니다.
- 비즈니스 로직의 위치가 논의되지 않습니다.
- 요청 라이프사이클이 보이지 않습니다.
- Django의 “마법”이 아키텍처 흐름을 가립니다.
아키텍처를 이해하지 못하면 Django는 통제된 혼돈처럼 느껴집니다.
이해하면 예측 가능하고 강력해집니다.
프로젝트 vs. 앱 — 가장 오해받는 개념
Django 프로젝트
프로젝트는 구성 컨테이너입니다. 다음을 정의합니다:
- 전역 설정
- 설치된 앱
- 미들웨어
- 루트 URL 구성
- ASGI/WSGI 진입점
프로젝트는 비즈니스 로직을 포함하지 않습니다. 프로젝트를 런타임 구성 및 환경 경계로 생각하세요.
Django 앱
앱은 기능의 모듈 단위이며 도메인 경계를 나타냅니다.
❌ 잘못된 모듈 사고
users_app/
orders_app/
payments_app/
✅ 더 나은 도메인‑지향 사고
accounts/
billing/
analytics/
core/
각 앱은 다음을 캡슐화해야 합니다:
- 모델
- 뷰
- URL
- 해당 영역에 관련된 도메인 로직
앱은 단순히 폴더가 아니라 응집된 도메인 모듈입니다.
Source: …
MTV Properly Explained
Django는 MTV 패턴을 따릅니다:
- Model
- Template
- View
이는 종종 MVC와 비교되지만 동일하지는 않습니다.
Conceptual Mapping
| Django | Classical MVC |
|---|---|
| Model | Model |
| Template | View |
| View | Controller |
Model
데이터 구조와 데이터베이스 상호작용을 나타냅니다.
- 스키마 정의
- ORM 로직 처리
- 데이터 동작 캡슐화
필요한 경우 도메인 규칙을 모델에 포함시켜야 합니다.
View
이름과 달리 Django의 View는 컨트롤러에 더 가깝게 동작합니다. 그것은:
- 요청을 수락하고
- 로직을 조정하며
- 모델과 상호작용하고
- 응답을 반환합니다
하지 말아야 할 것:
- 무거운 비즈니스 로직을 포함
- 대규모 데이터 변환 수행
- 코드가 쌓이는 덤핑 그라운드가 되는 것
Template
프레젠테이션을 담당합니다. API 기반 시스템(예: Django REST Framework)에서는 템플릿이 종종 직렬화기와 JSON 응답으로 대체됩니다.
Django 요청 라이프사이클 (실제로 일어나는 일)
이를 이해하는 것이 중요합니다.
- 클라이언트가 HTTP 요청을 보냅니다.
- 웹 서버가 요청을 Django에 전달합니다 (WSGI 또는 ASGI를 통해).
- 미들웨어가 요청을 처리합니다.
- URL 리졸버가 경로와 매칭합니다.
- 해당 뷰가 실행됩니다.
- 뷰가 모델 / 서비스와 상호작용합니다.
- Response 객체가 생성됩니다.
- 미들웨어가 응답을 처리합니다.
- 응답이 클라이언트에 반환됩니다.
핵심 인사이트: 모든 요청은 예측 가능한 파이프라인을 거칩니다. Django는 마법이 아니라 구조화된 오케스트레이션입니다.
모듈형 설계 조언 (중급 개발자처럼 생각하기)
프로젝트가 성장함에 따라 기본 Django 구조만으로는 충분하지 않게 됩니다.
1. 비대해진 뷰 피하기
Bad example
def create_order(request):
# validation
# business logic
# pricing calculation
# email sending
# inventory update
Solution: 비즈니스 로직을 다음과 같은 전용 레이어로 이동합니다:
services.py- 도메인 모듈
- 전용 로직 레이어
뷰는 조정 역할을 해야 하며, 비즈니스 규칙을 구현해서는 안 됩니다.
2. 서비스 레이어 도입
전형적인 앱 레이아웃:
billing/
models.py
views.py
services.py # write operations
selectors.py # read/query logic
이렇게 하면 로직이 체계적이고 테스트 가능해집니다.
3. 도메인 경계에서 사고하기
- ❌ 모든 것을 하나의 거대한 앱에 넣기
- ❌ 과도하게 조각난 마이크로 앱
✅ 좋은 실천
- 명확한 도메인 경계
- 높은 응집도
- 낮은 결합도
실제 환경 구조 패턴
성숙한 Django 시스템은 종종 다음과 같은 레이아웃으로 발전합니다:
project/
│
├── config/
│ ├── settings/
│ │ ├── base.py
│ │ ├── dev.py
│ │ └── prod.py
│
├── apps/
│ ├── accounts/
│ ├── billing/
│ ├── analytics/
│
├── core/
│ ├── middleware.py
│ ├── permissions.py
│
└── manage.py
프로덕션에서 흔히 보이는 패턴:
- 환경별로 설정을 분리
- 전용
apps/폴더 - 인프라와 도메인 로직을 명확히 구분
- 서비스와 셀렉터 패턴
- 중앙 집중식 설정
구조는 확장성을 지원해야 하며, 확장을 방해해서는 안 됩니다.
Common Mistakes Developers Make
-
Putting All Logic in Views
- 테스트하기 어려운 코드, 중복, 높은 결합도를 초래합니다.
-
Overusing Signals
- 시그널은 강력하지만 암묵적이며, 로직을 숨기고 보이지 않는 의존성을 만들며 디버깅을 어렵게 합니다. 신중하게 사용하세요.
-
Ignoring the Request Lifecycle
- 미들웨어나 URL 해석을 이해하지 못하면 디버깅이 고통스럽습니다.
-
Treating Apps as Random Containers
- 앱은 임의의 파일 그룹이 아니라 도메인 모듈을 나타내야 합니다.
-
Over‑engineering Too Early
- 모든 프로젝트가 복잡한 서비스 레이어, 깊은 폴더 구조, 마이크로서비스를 필요로 하는 것은 아닙니다. 간단하게 시작하고 필요에 따라 발전시키세요.
최종 생각
Django는 설계상 혼란스럽지 않습니다.
우리가 이를 절차적으로 배우고, 아키텍처적으로 배우지 않을 때 혼란스러워집니다.
다음 사항을 이해한다면:
- 프로젝트와 앱 경계
- MTV 개념
- 요청 라이프사이클
- 모듈식 구조 원칙
그러면 Django는 “마법”이 아니라는 것을 알게 됩니다.
예측 가능하고 확장 가능한 백엔드 프레임워크가 됩니다.
그리고 이것이 Django를 사용하는 것과 Django를 이해하는 것의 차이점입니다.