Skip to content

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 앱 생성

장고 앱 생성 명령어

장고 앱이 가져야할 각각의 파일명으로 앱 폴더를 생성

python manage.py startapp blog

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 - 데이터 모델

blog/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title
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단계: 앱 생성

python manage.py startapp blog

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단계: 앱 등록 및 마이그레이션

# settings.py에 'blog' 추가 후
python manage.py makemigrations
python manage.py migrate

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
관리 도구 기본 지원 없음 기본 관리 도구 체계를 지원하나, 커스텀 방식도 가능

실습 과제

  1. accounts 앱을 생성하고 사용자 프로필 모델 추가
  2. shop 앱을 생성하고 상품 모델 추가
  3. 각 앱을 관리자 사이트에 등록

정리

Django의 프로젝트/앱 구조는: - 체계적인 코드 구성: 기능별로 앱 분리 - 재사용성: 앱을 다른 프로젝트에서도 사용 가능 - 확장성: 새로운 기능은 새로운 앱으로 추가 - 관리 용이성: 각 앱이 독립적으로 관리됨

FastAPI의 자유로운 구조와 달리, Django는 정형화된 구조를 제공하여 대규모 프로젝트에서도 일관성 있는 개발이 가능합니다.

다음 장에서는 Django의 URL 라우팅과 뷰에 대해 자세히 알아보겠습니다!

Comments