[장고] 리액트 연동하기 (실습편)
웹 애플리케이션 개발에서 백엔드와 프론트엔드를 분리하여 개발하는 것은 일반적인 패턴입니다. 이번 글에서는 장고(Django)와 리액트(React)를 사용해 포럼 사이트를 구축하는 방법을 단계별로 알아보겠습니다. 이 튜토리얼은 가상 환경 설정부터 프로젝트 배포까지 모든 과정을 다룹니다.
전체적인 구성 요소
- 장고 백엔드: 사용자 인증, 데이터베이스 관리, API 제공
- 리액트 프론트엔드: 사용자 인터페이스, API와의 상호작용
1. 환경 설정 및 필수 라이브러리 설치
가상 환경 설정 및 필수 라이브러리 설치
우선, 가상 환경을 설정하고 필요한 라이브러리를 설치합니다. 이는 프로젝트 간의 의존성을 관리하는 데 도움을 줍니다.
python -m venv myenv
source myenv/bin/activate # 윈도우의 경우: myenv\\Scripts\\activate
pip install django djangorestframework django-cors-headers
2. 장고 프로젝트 설정
장고 프로젝트 및 앱 생성
장고 프로젝트를 생성하고 posts
라는 앱을 추가합니다. 이 앱은 게시물 관리를 담당하게 됩니다.
django-admin startproject blog
cd blog
django-admin startapp posts
settings.py
설정
INSTALLED_APPS
에 필요한 앱들을 추가합니다. corsheaders
는 리액트와의 CORS 문제를 해결하기 위해 필요합니다.
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'posts',
]
Django 프로젝트 설정 파일에 필요한 애플리케이션들을 추가하여 API와 CORS 기능을 사용할 수 있게 합니다.
CORS 설정
장고와 리액트가 다른 포트에서 실행되므로, CORS 설정이 필요합니다.
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
...
]
CORS_ORIGIN_ALLOW_ALL = True
3. 데이터 모델 설정
posts/models.py
파일 수정
포스트의 기본 모델을 정의합니다. User
모델과 연동하여 작성자를 관리합니다.
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=255)
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)
def __str__(self):
return self.title
Post
모델을 정의하여 포스트의 제목, 내용, 작성자, 생성일, 수정일을 저장합니다. 작성자는 User
모델과 외래키로 연결되어 있습니다.
마이그레이션 적용
모델을 데이터베이스에 반영합니다.
python manage.py makemigrations
python manage.py migrate
위 명령어들은 새로운 데이터베이스 스키마를 생성하고 적용하여 모델 변화를 데이터베이스에 반영합니다.
4. API 설정
posts/serializers.py
파일 생성 및 수정
모델 데이터를 JSON 형태로 직렬화하기 위한 시리얼라이저를 설정합니다.
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
PostSerializer
를 정의하여 Post
모델의 모든 필드를 JSON으로 변환할 수 있게 합니다.
posts/views.py
파일 수정
ViewSet을 이용해 API 엔드포인트를 설정합니다.
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
PostViewSet
을 설정하여 기본적인 CRUD 기능을 제공하는 API 엔드포인트를 생성합니다.
posts/urls.py
파일 생성 및 수정
ViewSet을 이용해 API 엔드포인트를 설정합니다.
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
라우터를 설정하고 PostViewSet
을 등록하여 /posts
엔드포인트를 통해 API에 접근할 수 있게 합니다.
blog/urls.py
파일 수정
API URL을 메인 URL 설정에 포함시킵니다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('posts.urls')),
]
메인 URL 설정 파일에 posts
앱의 URL을 포함시켜 /api/posts
경로로 API 요청을 처리합니다.
5. 리액트 프로젝트 설정
리액트 프로젝트 생성 및 설정
장고 프로젝트의 루트 디렉토리에서 create-react-app
을 사용하여 새로운 리액트 프로젝트를 생성합니다.
npx create-react-app frontend
cd frontend
Axios 설치
리액트에서 API 호출을 쉽게 하기 위해 Axios를 설치합니다.
npm install axios
npm start
6. 리액트와 API 연동
frontend/src/App.js
파일 수정
리액트 앱에서 장고 API와 상호작용하도록 설정합니다.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [posts, setPosts] = useState([]);
useEffect(() => {
axios.get('/api/posts/')
.then(response => {
setPosts(response.data);
})
.catch(error => {
console.error('There was an error fetching the posts!', error);
});
}, []);
return (
<div>
<h1>Forum Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
<p><em>by {post.author}</em></p>
</li>
))}
</ul>
</div>
);
}
export default App;
리액트 컴포넌트에서 Axios를 사용하여 API로부터 데이터를 가져오고 이를 화면에 렌더링합니다.
7. 리액트 빌드 및 장고에서 서빙
리액트 빌드
리액트 프로젝트 디렉토리에서 다음 명령어를 실행하여 빌드합니다.
npm run build
빌드된 파일들은 frontend/build
디렉토리에 생성됩니다.
장고 설정 파일 수정
settings.py
에 정적 파일 설정을 추가합니다.
import os
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend/build/static'),
]
장고 뷰 설정
리액트 앱을 서빙하는 뷰를 설정합니다.
from django.shortcuts import render
def index(request):
return render(request, 'frontend/build/index.html')
URL 설정
메인 URL 설정에 리액트 앱을 서빙하는 URL을 추가합니다.
from django.urls import path, include
from .views import index
urlpatterns = [
path('', index),
path('api/', include(router.urls)),
]
8. 장고 서버 실행
python manage.py runserver
이제 브라우저에서 http://127.0.0.1:8000
에 접속하면 리액트 앱이 표시되고, API를 통해 포스트 데이터를 가져올 수 있습니다.
요약
이번 포스트에서는 장고와 리액트를 사용하여 포럼 사이트를 구축하는 과정을 다루었습니다. 이 튜토리얼을 통해 다음을 학습했습니다:
- 가상 환경 설정 및 필수 라이브러리 설치
- 장고 프로젝트 설정 및 API 제공
- 리액트 프로젝트 생성 및 API와의 연동
- 리액트 빌드 파일을 장고에서 서빙
- 장고 서버를 실행하여 리액트 앱과 API 통합
이 기본적인 설정을 통해 포럼 사이트의 기본 구조를 만들 수 있습니다. 이후에는 사용자 인증, 게시물 작성, 댓글 기능 등을 추가하여 포럼 사이트를 더욱 완성할 수 있습니다.
추가 참고 사항
Proxy 설정:
frontend/package.json
에 프록시 설정을 추가하여 개발 서버와 API 서버 간의 포트 차이를 해결할 수 있습니다.CSRF 보호: Axios를 사용할 때 CSRF 토큰을 설정하여 보안을 강화할 수 있습니다. 이를 위해 Axios 기본 설정에 다음 코드를 추가합니다:
axios.defaults.xsrfCookieName = "csrftoken"; axios.defaults.xsrfHeaderName = "X-CSRFToken";
Eject 없이 설정 변경: 리액트 프로젝트를 eject하지 않고도 Sass 및 기타 설정을 적용할 수 있습니다. 이를 통해 프로젝트 설정을 보다 간편하게 유지할 수 있습니다.
이와 같은 추가 설정은 프로젝트의 보안성과 유지보수성을 높이는 데 기여합니다.