안녕하세요! 오늘은 Django 공식 문서의 "Django 훑어보기" 섹션을 실제로 따라하면서 뉴스 사이트를 처음부터 끝까지 만들어보겠습니다. Django를 처음 접하는 분들도 쉽게 따라할 수 있도록 각 단계마다 자세한 설명과 함께 1, 2편으로 진행하겠습니다.
프로젝트 생성과 초기 설정
먼저 Django 프로젝트를 생성하고 기본 설정을 해보겠습니다.
# Django 설치
pip install django
# 뉴스사이트 프로젝트 생성
django-admin startproject newssite
cd newssite
# news 앱 생성
python manage.py startapp news
프로젝트를 생성하면 이런 구조가 만들어집니다
newssite/
├── manage.py # Django 관리 명령어 도구
├── newssite/ # 프로젝트 설정 폴더
│ ├── settings.py # 전체 설정 파일
│ ├── urls.py # 메인 URL 설정
│ └── wsgi.py # 웹 서버 연동
└── news/ # 뉴스 앱 폴더
├── models.py # 데이터베이스 모델
├── views.py # 비즈니스 로직
├── admin.py # 관리자 설정
└── apps.py # 앱 설정
앱을 Django에 등록하기
생성한 앱을 Django가 인식할 수 있도록 settings.py에 등록해야 합니다 settings.py 파일에 가면 밑에 처럼 기본 값으로 설정되어 있습니다.
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-kh^3hh!kgy=h+@#$-lks2oujkj1_(@tlt-ab22+(4tc7&1%#jq'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles'
]
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',
]
......
해당 INSTALLED_APPS에서 우리가 만든 앱을 추가해주세요. Django는 INSTALLED_APPS에 등록된 앱만 인식합니다. 등록하지 않으면 모델, 템플릿, URL 등 아무것도 작동하지 않습니다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'news' # 해당 앱을 등록
]
데이터베이스 모델 설계
이제 뉴스 사이트에 필요한 데이터 구조를 정의해보겠습니다. Django의 **ORM(Object-Relational Mapping)**을 사용하면 SQL을 직접 작성하지 않고도 파이썬 코드로 데이터베이스를 다룰 수 있습니다.
# news/models.py
from django.db import models
class Reporter(models.Model):
"""기자 정보를 저장하는 모델"""
full_name = models.CharField(max_length=70, verbose_name='기자명')
def __str__(self):
return self.full_name
class Meta:
verbose_name = '기자'
verbose_name_plural = '기자 목록'
class Article(models.Model):
"""기사 정보를 저장하는 모델"""
pub_date = models.DateField(verbose_name='발행일')
headline = models.CharField(max_length=200, verbose_name='제목')
content = models.TextField(verbose_name='내용')
reporter = models.ForeignKey(
Reporter,
on_delete=models.CASCADE,
verbose_name='기자'
)
def __str__(self):
return self.headline
class Meta:
verbose_name = '기사'
verbose_name_plural = '기사 목록'
ordering = ['-pub_date'] # 최신 기사부터 정렬
모델의 핵심 포인트
- models.Model 상속: Django가 데이터베이스 테이블로 인식
- 필드 타입: CharField, TextField, DateField 등으로 데이터 유형 정의
- 외래키 관계: ForeignKey로 Reporter와 Article 연결
- __str__ 메서드: 객체를 문자열로 표현하는 방법 정의
- Meta 클래스: 모델의 메타데이터 설정
마이그레이션으로 데이터베이스 테이블 생성
모델을 정의했으니 이제 실제 데이터베이스에 테이블을 만들어야 합니다. Django의 마이그레이션 시스템을 사용하면 이 과정이 자동화됩니다.
# 1단계: 모델 변경사항을 마이그레이션 파일로 생성
python manage.py makemigrations
# 출력 결과:
# Migrations for 'news':
# news/migrations/0001_initial.py
# - Create model Reporter
# - Create model Article
# 2단계: 실제 데이터베이스에 테이블 생성
python manage.py migrate
마이그레이션이 하는 일
- 모델 분석: Django가 우리 모델 코드를 분석
- SQL 생성: 적절한 CREATE TABLE 문 자동 생성
- 테이블 생성: 데이터베이스에 실제 테이블 생성
- 관계 설정: 외래키, 인덱스 등도 자동 처리 예를 들어, 위 모델은 대략 이런 SQL로 변환됩니다
- 예를 들어, 위 모델은 대략 이런 SQL로 변환됩니다
CREATE TABLE news_reporter (
id INTEGER PRIMARY KEY AUTOINCREMENT,
full_name VARCHAR(70) NOT NULL
);
CREATE TABLE news_article (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pub_date DATE NOT NULL,
headline VARCHAR(200) NOT NULL,
content TEXT NOT NULL,
reporter_id INTEGER NOT NULL REFERENCES news_reporter (id)
);
Django ORM으로 데이터 다루기
이제 Django가 제공하는 ORM를 사용해서 데이터를 조작해보겠습니다. 해당 밑 코드블럭을 참조 해주세요.
# Django 셸 실행 (대화형 파이썬 셸)
python manage.py shell
# 모델 import
>>> from news.models import Article, Reporter
>>> from datetime import date
# 아직 데이터가 없음
>>> Reporter.objects.all()
<QuerySet []>
# 새 기자 생성
>>> r = Reporter(full_name="김기자")
>>> r.save() # 꼭 save()를 호출해야 DB에 저장됨!
# ID가 자동으로 생성됨
>>> r.id
1
# 이제 데이터베이스에 저장됨
>>> Reporter.objects.all()
<QuerySet [<Reporter: 김기자>]>
# JOIN을 사용한 복잡한 쿼리도 간단하게!
>>> Article.objects.filter(reporter__full_name__startswith="김")
<QuerySet [<Article: Django 학습 완료!>]>
# 데이터 수정
>>> r.full_name = "박기자"
>>> r.save()
# 데이터 삭제 (관련 Article도 CASCADE로 함께 삭제)
>>> r.delete()
# 기본 조회
>>> Reporter.objects.get(id=1)
<Reporter: 김기자>
# 부분 일치 조회
>>> Reporter.objects.get(full_name__startswith="김")
<Reporter: 김기자>
>>> Reporter.objects.get(full_name__contains="기자")
<Reporter: 김기자>
# 존재하지 않는 데이터 조회시 예외 발생
>>> Reporter.objects.get(id=999)
DoesNotExist: Reporter matching query does not exist.
# 기사 생성 (기자와 연결)
>>> a = Article(
... pub_date=date.today(),
... headline="Django 학습 완료!",
... content="오늘 Django를 배웠습니다.",
... reporter=r
... )
>>> a.save()
# 관계를 통한 데이터 접근
>>> a.reporter.full_name # 기사 → 기자
'김기자'
>>> r.article_set.all() # 기자 → 기사들 (Django가 자동으로 _set 속성 생성)
<QuerySet [<Article: Django 학습 완료!>]>
Django ORM의 핵심 장점은 SQL 없이 파이썬 코드만으로 데이터베이스를 조작할 수 있다는 것입니다. 복잡한 JOIN 연산도 Article.objects.filter(reporter__name="김기자") 같은 직관적인 문법으로 표현하며, SQLite에서 PostgreSQL로 DB를 바꿔도 코드 수정 없이 그대로 동작합니다.
Reference
'Django' 카테고리의 다른 글
장고 공식 문서 훑어보기 2편 (4) | 2025.08.24 |
---|