[장고] 리액트 연동하기 (실습편)

소요 시간: 10분

웹 애플리케이션 개발에서 백엔드와 프론트엔드를 분리하여 개발하는 것은 일반적인 패턴입니다. 이번 글에서는 장고(Django)와 리액트(React)를 사용해 포럼 사이트를 구축하는 방법을 단계별로 알아보겠습니다. 이 튜토리얼은 가상 환경 설정부터 프로젝트 배포까지 모든 과정을 다룹니다.


전체적인 구성 요소

  1. 장고 백엔드: 사용자 인증, 데이터베이스 관리, API 제공
  2. 리액트 프론트엔드: 사용자 인터페이스, 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를 통해 포스트 데이터를 가져올 수 있습니다.


요약

이번 포스트에서는 장고와 리액트를 사용하여 포럼 사이트를 구축하는 과정을 다루었습니다. 이 튜토리얼을 통해 다음을 학습했습니다:

  1. 가상 환경 설정 및 필수 라이브러리 설치
  2. 장고 프로젝트 설정 및 API 제공
  3. 리액트 프로젝트 생성 및 API와의 연동
  4. 리액트 빌드 파일을 장고에서 서빙
  5. 장고 서버를 실행하여 리액트 앱과 API 통합

이 기본적인 설정을 통해 포럼 사이트의 기본 구조를 만들 수 있습니다. 이후에는 사용자 인증, 게시물 작성, 댓글 기능 등을 추가하여 포럼 사이트를 더욱 완성할 수 있습니다.


추가 참고 사항

이와 같은 추가 설정은 프로젝트의 보안성과 유지보수성을 높이는 데 기여합니다.

장고 리스트