본문으로 건너뛰기
김신건의 로그

[Django] 첫 프로젝트 튜토리얼: 순차 학습

· 수정 · 📖 약 2분 · 567자/단어 #django #tutorial #beginner #python
Django tutorial, Django 첫 프로젝트, startproject, startapp, manage.py runserver, Django getting started

정의

Django 를 처음 접하는 사람 을 위한 순차 학습 페이지. 투표 앱 (polls) 을 만들며 Django 의 핵심 개념을 익힌다.

먼저 django-overview 로 MTV 패턴과 프로젝트 구조를 파악한 후 이 페이지로.

학습 순서 (전체 지도)

flowchart TB
    S["1. 설치 + startproject"] --> T["2. runserver 확인"]
    T --> A["3. app 생성 (startapp)"]
    A --> M["4. 모델 (Model)"]
    M --> Adm["5. Admin 사이트"]
    Adm --> V["6. View + URL"]
    V --> Tpl["7. Template"]
    Tpl --> F["8. Form"]
    F --> Test["9. Test"]
    Test --> D["10. Deploy"]

이 순서로 페이지를 따라가면 Django 의 90% 를 이해.

사전 준비

# Python 3.12+ 권장 (Django 6.0 최소 3.12)
python --version

# 가상환경
python -m venv .venv
source .venv/bin/activate       # macOS/Linux
# .venv\Scripts\activate         # Windows

# Django 6.0 설치
pip install django
python -m django --version

Step 1. 프로젝트 시작

django-admin startproject mysite
cd mysite
mysite/
├── manage.py           # CLI 진입점
└── mysite/
    ├── __init__.py
    ├── settings.py     # 설정 파일
    ├── urls.py         # 루트 URL 설정
    ├── asgi.py         # ASGI 서버
    └── wsgi.py         # WSGI 서버
python manage.py runserver
# → http://127.0.0.1:8000/ 접속

TIP

manage.py프로젝트 마다 하나. django-admin전역 명령. 실제로 프로젝트 안에서는 manage.py 를 쓴다.

Step 2. App 생성

Django 의 app = 재사용 가능한 모듈. 프로젝트는 여러 app 의 조립.

python manage.py startapp polls
polls/
├── __init__.py
├── admin.py           # Admin 등록
├── apps.py            # App 설정
├── models.py          # 모델
├── views.py           # 뷰
├── tests.py           # 테스트
└── migrations/        # 마이그레이션 파일

mysite/settings.py 에 app 등록:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls.apps.PollsConfig',   # ← 추가
]

Step 3. 모델 정의

polls/models.py:

from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='choices')
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

Migration 생성 + DB 반영:

python manage.py makemigrations polls
python manage.py migrate

자세한 필드 종류는 django-models-fields, migrations 는 django-migrations.

Step 4. Admin 사이트

python manage.py createsuperuser
# 이름, 이메일, 비밀번호 입력

polls/admin.py:

from django.contrib import admin
from .models import Question, Choice

@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
    list_display = ('question_text', 'pub_date')
    list_filter = ('pub_date',)
    search_fields = ('question_text',)

@admin.register(Choice)
class ChoiceAdmin(admin.ModelAdmin):
    list_display = ('choice_text', 'question', 'votes')
python manage.py runserver
# http://127.0.0.1:8000/admin/ 접속 → 위 계정으로 로그인

자세한 건 django-admin.

Step 5. View + URL

polls/views.py:

from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from .models import Question

def index(request):
    latest_questions = Question.objects.order_by('-pub_date')[:5]
    return render(request, 'polls/index.html', {
        'latest_questions': latest_questions,
    })

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

polls/urls.py:

from django.urls import path
from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
]

mysite/urls.py:

from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/', include('polls.urls')),
]

자세한 건 django-urls, django-views, django-shortcuts-decorators.

Step 6. Template

polls/templates/polls/index.html:

{% extends "base.html" %}

{% block content %}
<h1>최근 질문</h1>
{% if latest_questions %}
    <ul>
    {% for q in latest_questions %}
        <li>
            <a href="{% url 'polls:detail' q.id %}">{{ q.question_text }}</a>
        </li>
    {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}
{% endblock %}

자세한 건 django-templates.

Step 7. Form

polls/forms.py:

from django import forms
from .models import Question

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['question_text', 'pub_date']
        widgets = {
            'pub_date': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
        }

자세한 건 django-forms, django-modelforms, django-formsets.

Step 8. Test

# polls/tests.py
from django.test import TestCase
from django.utils import timezone
from .models import Question

class QuestionModelTests(TestCase):
    def test_str(self):
        q = Question.objects.create(question_text='Test?', pub_date=timezone.now())
        self.assertEqual(str(q), 'Test?')

    def test_recent_questions(self):
        Question.objects.create(question_text='Old', pub_date=timezone.now() - timezone.timedelta(days=10))
        Question.objects.create(question_text='New', pub_date=timezone.now())
        recent = Question.objects.order_by('-pub_date').first()
        self.assertEqual(recent.question_text, 'New')
python manage.py test polls

자세한 건 django-testing.

Step 9. Deploy

# 1. 정적 파일 collect
python manage.py collectstatic

# 2. WSGI 서버 (gunicorn)
pip install gunicorn
gunicorn mysite.wsgi:application

# 3. 환경변수
export DJANGO_SETTINGS_MODULE=mysite.settings.production
export DATABASE_URL=postgres://...

# 4. 필수 체크
python manage.py check --deploy

자세한 건 django-deployment, django-settings.

Django vs 다른 프레임워크

FeatureDjangoRailsSpring BootFastAPIExpress
언어PythonRubyJavaPythonNode.js
Batteries포함포함starter최소최소
ORMORM 내장ActiveRecordJPA/HibernateSQLAlchemy없음 (선택)
Admin UI내장없음 (gem)없음없음없음
Migrations내장Active RecordFlywayAlembic별도
TemplateDTLERBThymeleafJinja2EJS/Pug
Forms내장Form helpersSpring MVCPydantic없음
학습 곡선완만완만가파름매우 완만매우 완만
규모대형대형대형소-중자유

Django 는 “완벽주의자를 위한 프레임워크” - 컨벤션이 많아 처음에는 답답할 수 있지만 대규모 프로젝트에서는 일관성 + 안전 이 큰 장점.

다음 단계

이 튜토리얼 후 학습 순서 권장:

  1. django-models-fields - 필드 종류
  2. django-queryset - ORM 쿼리
  3. django-urls - URL routing
  4. django-views - View 상세
  5. django-templates - 템플릿 문법
  6. django-forms - 폼 처리
  7. django-admin - 관리자 커스터마이즈
  8. django-auth - 인증
  9. django-cache - 캐싱
  10. django-testing - 테스트

관련 위키

이 글의 용어 (19개)
[Django] 개요와 프로젝트 구조django
정의 Django는 2003년 시작된 Python 풀스택 웹 프레임워크. "Web framework for perfectionists with deadlines"라는 모토대로 b…
[Django] 마이그레이션: makemigrations, migrate, 데이터 마이그레이션django
정의 Django 마이그레이션은 모델 변경을 DB 스키마 변경으로 변환·기록하는 시스템. 는 모델과 현재 마이그레이션 상태를 비교해 새 마이그레이션 파일 생성. 는 DB에 적용.…
[Django] 배포: Gunicorn, Uvicorn, whitenoise, Dockerdjango
정의 Django 프로덕션 배포는 WSGI/ASGI 서버 + 리버스 프록시 + 정적 파일 + DB + 캐시 + 큐 조합. runserver는 개발 전용. nginx + gunic…
[Django] 인증: User, login, permissionsdjango
정의 Django는 User 모델, 인증·세션, 권한·그룹을 기본 제공한다. 앱이 핵심. 비밀번호 해싱(PBKDF2, scrypt, Argon2), 세션, 권한, 그룹, 비밀번호…
[Django] 테스트: TestCase, Client, factory_boydjango
정의 Django는 표준 라이브러리 기반 TestCase를 제공한다. 트랜잭션 격리, fixtures, test client, DB 셋업 자동화. 실무는 + 가 사실상 표준. 기…
[Django] Admin: 자동 생성 관리자 페이지django
정의 Django Admin은 모델 등록만으로 CRUD UI 자동 생성하는 내장 백오피스. 내부 운영 도구, 콘텐츠 관리(CMS) 등에 강력. 권한 시스템 통합. Rails에는 …
[Django] Caching: per-site, per-view, low-leveldjango
정의 Django 캐싱은 데이터/페이지 재생성 비용 회피의 핵심. 4단계 그래뉴얼리티 제공: site-wide → per-view → template fragment → low-…
[Django] Form과 ModelFormdjango
정의 Django Form은 사용자 입력 정의·검증·렌더링·바인딩을 통합. 일반 은 임의 필드, 은 모델 자동 매핑. 검증과 보안(CSRF, SQL 인젝션 방지) 내장. Form…
[Django] Formsets: 여러 폼 동시 처리django
정의 Formset = 여러 폼을 한 페이지에서 동시 처리. "상품 3개 한 번에 등록", "주문 상세 여러 줄 편집" 같은 시나리오. 3가지 종류 1. 기본 FormSet Te…
[Django] Management Commandsdjango
정의 Django 커스텀 명령은 형태로 실행되는 CLI 도구. 정기 작업(cron + management command), 데이터 마이그레이션, import/export, 디버깅…
[Django] Model과 Field 타입django
정의 Django 모델은 DB 테이블의 Python 표현이다. 상속, 클래스 속성 = 컬럼, 메타 클래스 = 테이블 설정. 모델 정의 후 + 로 DB 스키마 자동 생성. 기본 정…
[Django] ModelForm: 모델 기반 폼 자동 생성django
정의 ModelForm = Model 로부터 Form 자동 생성. 필드 반복 정의 없이 CRUD 폼 완성. 일반 Form 은 참고. 왜 ModelForm? 기본 사용 vs [!W…
[Django] QuerySet과 Managerdjango
정의 QuerySet은 DB 쿼리를 lazy하게 빌드하는 객체. , 같은 메서드를 체이닝해도 실제 SQL 실행은 평가 시점( , , , slice 등)에 한 번 발생. Manag…
[Django] settings 관리: 환경 분리, secrets, 12-factordjango
정의 Django settings는 단일 Python 파일에 모든 설정을 두는 게 기본이지만, 환경별 분리·비밀 정보 분리·12-factor 원칙 적용이 실무 표준. 개발/스테이…
[Django] Shortcuts + Decorators: render, redirect, get_object_or_404django
정의 Django 의 View 작성을 간결하게 하는 shortcut 함수들 + view 에 공통 기능을 붙이는 decorator 들. Shortcuts (django.shortc…
[Django] Template 언어: 태그, 필터, 상속django
정의 Django Template Language (DTL)는 HTML과 Python 사이의 안전한 표현 언어. 임의 Python 실행 차단(보안), 로 변수, 로 태그, 로 필…
[Django] URL 디스패치: path, re_path, includedjango
정의 Django는 URL 패턴 리스트로 요청을 view에 라우팅한다. 1.01.x는 (regex만), 2.0+ (간결한 converter 문법)와 (regex) 두 방식. 기본…
[Django] View: 함수 기반 vs 클래스 기반django
정의 Django View는 HTTP 요청을 받아 응답을 반환하는 callable. 두 스타일이 공존. - FBV (Function-Based View): 일반 함수. 간단하고 …
[Python] asyncio: 비동기 프로그래밍python
정의 asyncio 는 Python 의 표준 비동기 I/O 라이브러리 (3.4+). event loop 위에서 coroutine 을 스케줄링. 기본 병렬 실행 gather 세 요…

이 개념을 다룬 위키 페이지 (1)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기