[Django] 개요와 프로젝트 구조
django overview, django project structure, django app, MTV pattern, django architecture
정의
Django는 2003년 시작된 Python 풀스택 웹 프레임워크. “Web framework for perfectionists with deadlines”라는 모토대로 batteries-included(ORM, 관리자, 인증, 폼, 마이그레이션, 캐싱 등 기본 내장). MTV(Model-Template-View) 아키텍처. Instagram, Pinterest, Mozilla 등 대규모 운영 사례.
MTV 패턴
전통적인 MVC와 약간 다른 명명.
| Django | 전통 MVC | 역할 |
|---|---|---|
| Model | Model | DB 스키마와 비즈니스 로직 |
| Template | View | HTML 렌더링 |
| View | Controller | HTTP 요청 처리 |
| URL Dispatcher | Router | URL → View 매핑 |
요청 흐름: URL → View → (Model 조회/변경) → Template 렌더링 → Response
프로젝트 구조
django-admin startproject myproject
cd myproject
python manage.py startapp blog
myproject/
├── manage.py # CLI 진입점
├── myproject/ # 프로젝트 설정 패키지
│ ├── __init__.py
│ ├── settings.py # 설정
│ ├── urls.py # 루트 URL conf
│ ├── asgi.py # ASGI 진입점
│ └── wsgi.py # WSGI 진입점
├── blog/ # 앱
│ ├── __init__.py
│ ├── admin.py # 관리자 등록
│ ├── apps.py # 앱 설정
│ ├── models.py # 데이터 모델
│ ├── views.py # 뷰
│ ├── urls.py # 앱별 URL (관례)
│ ├── tests.py
│ └── migrations/ # DB 마이그레이션
└── templates/ # 템플릿 (관례)
프로젝트 = 사이트, 앱 = 기능 단위. 한 프로젝트에 여러 앱. 앱은 독립적이고 재사용 가능하도록 작성.
첫 모델
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
마이그레이션 생성과 적용:
python manage.py makemigrations
python manage.py migrate
첫 뷰와 URL
# blog/views.py
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects.all()
return render(request, "blog/post_list.html", {"posts": posts})
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="post-list"),
]
# myproject/urls.py
from django.urls import include, path
urlpatterns = [
path("blog/", include("blog.urls")),
]
템플릿
{# templates/blog/post_list.html #}
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.body|truncatewords:30 }}</p>
{% empty %}
<p>No posts.</p>
{% endfor %}
개발 서버
python manage.py runserver # localhost:8000
python manage.py runserver 8080
python manage.py runserver 0.0.0.0:8000 # 외부 접속
프로덕션엔 절대 사용 X. Gunicorn/Uvicorn + nginx.
settings.py 핵심
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog", # 우리 앱
]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "mydb",
"USER": "myuser",
"PASSWORD": "...",
"HOST": "localhost",
"PORT": "5432",
}
}
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",
]
DEBUG = True # 프로덕션에선 반드시 False
SECRET_KEY = "..." # 절대 커밋 X
ALLOWED_HOSTS = ["example.com"]
manage.py 자주 쓰는 명령
python manage.py startapp blog # 앱 생성
python manage.py makemigrations # 마이그레이션 파일 생성
python manage.py migrate # DB에 적용
python manage.py createsuperuser # 관리자 계정
python manage.py shell # IPython/REPL
python manage.py dbshell # DB CLI
python manage.py collectstatic # 정적 파일 수집
python manage.py test # 테스트
python manage.py runserver
Django vs Flask vs FastAPI
| Django | Flask | FastAPI | |
|---|---|---|---|
| 스타일 | 배터리 포함 | 마이크로 | API 우선 |
| ORM | 내장 | SQLAlchemy 등 | 외부 |
| 관리자 | 내장 | X | X |
| 비동기 | 부분 (3.1+) | 부분 | 네이티브 |
| 학습 곡선 | 중 | 낮 | 중 |
| 적합 | 일반 웹앱, CMS | 작은 API/앱 | API, 마이크로서비스 |
버전과 LTS
| 버전 | 출시 | 지원 종료 | 비고 |
|---|---|---|---|
| 4.2 LTS | 2023-04 | 2026-04 | 이전 LTS |
| 5.0 | 2023-12 | 2025-04 | |
| 5.1 | 2024-08 | 2025-12 | |
| 5.2 LTS | 2025-04 | 2028-04 | 현재 LTS |
LTS는 3년 지원. 프로덕션은 LTS 권장.
💬 댓글