Django 프로젝트 구조와 앱
FastAPI는 단일 파일에서 시작할 수 있지만, Django는 처음부터 체계적인 프로젝트 구조를 제공합니다. 이번 장에서는 Django의 프로젝트와 앱 개념을 이해해보겠습니다.
1. Django 프로젝트 vs 앱
개념 이해
- 프로젝트(Project): 전체 웹 애플리케이션
- 앱(App): 프로젝트 내의 기능별 모듈
FastAPI와 비교하면:
# FastAPI: 단일 파일 또는 패키지 구조
fastapi_app/
├── main.py
├── routers/
│ ├── users.py
│ └── posts.py
└── models/
# Django: 프로젝트와 앱 구조
django_project/
├── manage.py # 관리명령 진입점
├── mysite/ # 프로젝트 설정
├── blog/ # blog
└── accounts/ # 사용자 앱
2. Django 프로젝트 구조 상세
mysite/
├── manage.py # 프로젝트 관리 스크립트
├── db.sqlite3 # SQLite 데이터베이스 (migrate 후 생성)
└── mysite/ # 프로젝트 패키지
├── __init__.py # Python 패키지 표시
├── settings.py # 프로젝트 설정
├── urls.py # 최상위 URL 설정
├── asgi.py # ASGI 진입점
└── wsgi.py # WSGI 진입점
핵심 파일 설명
settings.py - 프로젝트의 모든 설정
# 주요 설정 항목
SECRET_KEY = 'django-insecure-...' # 보안 키
DEBUG = True # 개발 모드
ALLOWED_HOSTS = [] # 허용된 호스트
# 현재 프로젝트에 활성화된 장고 앱 목록
INSTALLED_APPS = [
'django.contrib.admin', # 관리자 사이트
'django.contrib.auth', # 인증 시스템
'django.contrib.contenttypes',
'django.contrib.sessions', # 세션 관리
'django.contrib.messages', # 메시지 프레임워크
'django.contrib.staticfiles', # 정적 파일 관리
]
# 데이터베이스 설정 (기본: SQLite)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
FastAPI와 비교
- Django: settings.py에 중앙집중식 관리 (기본에서 구성)
- FastAPI: 간결하게 config.py를 두나, Django처럼 settings를 두기도 합니다.
urls.py - URL 라우팅
mysite/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls), # 관리자 사이트
# path('blog/', include('blog.urls')), # 앱 URL 포함
]
3. Django 앱 생성
장고 앱 생성 명령어
장고 앱이 가져야할 각각의 파일명으로 앱 폴더를 생성
Warning
장고 앱 이름은 한 프로젝트 내에서 중복될 수 없습니다. 유일해야만 합니다.
생성된 앱 폴더는 아래와 같으며, 내부 구현은 없는 빈 파일들입니다.
blog/
├── __init__.py
├── admin.py # 관리자 사이트 설정
├── apps.py # 앱 설정
├── migrations/ # 데이터베이스 마이그레이션
│ └── __init__.py
├── models.py # 데이터 모델
├── tests.py # 테스트 코드
└── views.py # 뷰 함수
앱 등록
프로젝트 내에서 사용할 장고 앱은 반드시 settings.INSTALLED_APPS 리스트에 등록해야만,
현 프로젝트 내에서 장고 앱으로서 대접(ex: 모델/템플릿/마이그레이션 자동 인식 등)을 받습니다.
mysite/settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog", # 새로 생성한 앱 추가
]
Tip
앱을 프로젝트에 등록하더라도 URL Patterns는 "앱/urls.py"는 자동으로 임포트되진 않습니다.
"앱/urls.py"는 직접 include를 해야만 합니다.
4. 앱의 각 파일 역할
models.py - 데이터 모델
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Text, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Post(Base):
# 장고 모델에서는 디폴트 테이블명 "앱이름_모델명" 사용
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True, index=True)
title: Mapped[str] = mapped_column(String(200))
content: Mapped[str] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(
server_default=func.now(),
nullable=False
)
def __str__(self) -> str:
return self.title
from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field
# 기본 모델 (공통 필드)
class PostBase(SQLModel):
title: str = Field(max_length=200, description="포스트 제목")
content: str = Field(default="", description="포스트 내용")
# 데이터베이스 테이블 모델
class Post(PostBase, table=True):
__tablename__ = "posts"
id: Optional[int] = Field(default=None, primary_key=True, index=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
def __str__(self) -> str:
return self.title
# API 요청 모델 (생성시 사용)
class PostCreate(PostBase):
pass # title, content만 받음
# API 응답 모델 (조회시 사용)
class PostRead(PostBase):
id: int
created_at: datetime
# API 업데이트 모델
class PostUpdate(SQLModel):
title: Optional[str] = Field(default=None, max_length=200)
content: Optional[str] = Field(default=None)
views.py - 비즈니스 로직
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("블로그 홈페이지입니다.")
# FastAPI의 라우터 함수와 비교
# @app.get("/")
# async def index():
# return {"message": "블로그 홈페이지입니다."}
admin.py - 관리자 사이트
from django.contrib import admin
from .models import Post
admin.site.register(Post) # 관리자 사이트에 모델 등록
# FastAPI는 관리자 사이트를 직접 구현해야 함
5. 실습: 블로그 앱 만들기
1단계: 앱 생성
2단계: 모델 정의
# blog/models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at'] # 최신글 먼저
def __str__(self):
return self.title
3단계: 앱 등록 및 마이그레이션
4단계: 관리자 사이트 등록
# blog/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'created_at']
list_filter = ['created_at', 'author']
search_fields = ['title', 'content']
5단계: 관리자 계정 생성 및 확인
python manage.py createsuperuser
# Username: admin
# Email: admin@example.com
# Password: ********
python manage.py runserver
# http://127.0.0.1:8000/admin/ 접속
6. 프로젝트 구조 확장
실제 프로젝트에서는 여러 앱을 조합하여 사용합니다:
mysite/
├── manage.py
├── mysite/
├── blog/ # 블로그 기능
├── accounts/ # 사용자 인증
├── api/ # API 엔드포인트
├── static/ # CSS, JS, 이미지
├── media/ # 사용자 업로드 파일
└── templates/ # HTML 템플릿
7. Django 앱 설계 원칙
- 재사용성을 목적으로한 폴더
- 재사용성을 염두에 두지 않는다면, 단일 앱으로 개발해도 OK.
- 예:
blog,shop,accounts
8. FastAPI와 Django 구조 비교
| 항목 | FastAPI | Django |
|---|---|---|
| 프로젝트 생성 | 기본 지원 없음 | python -m django startproject 명령 |
| 모듈화 | 기본 지원 없음 | 멀티 앱 구조uv |
| URL 라우팅 | 데코레이터 | URLconf |
| 관리 도구 | 기본 지원 없음 | 기본 관리 도구 체계를 지원하나, 커스텀 방식도 가능 |
실습 과제
accounts앱을 생성하고 사용자 프로필 모델 추가shop앱을 생성하고 상품 모델 추가- 각 앱을 관리자 사이트에 등록
정리
Django의 프로젝트/앱 구조는: - 체계적인 코드 구성: 기능별로 앱 분리 - 재사용성: 앱을 다른 프로젝트에서도 사용 가능 - 확장성: 새로운 기능은 새로운 앱으로 추가 - 관리 용이성: 각 앱이 독립적으로 관리됨
FastAPI의 자유로운 구조와 달리, Django는 정형화된 구조를 제공하여 대규모 프로젝트에서도 일관성 있는 개발이 가능합니다.
다음 장에서는 Django의 URL 라우팅과 뷰에 대해 자세히 알아보겠습니다!