Post

Django: DRF Single Model

Django REST Framework를 활용한 단일 모델 데이터 처리 및 API 구현 가이드.

Django: DRF Single Model

단일 모델에서 데이터를 조회하고 직렬화(Serialization)하여 JSON으로 응답하기를 반복합니다. Django REST Framework(DRF)에서 이를 효율적으로 처리하는 방법에 대해 알아보겠습니다.

ModelSerializer ModelSerializer는 모델의 필드를 직렬화하여 데이터 포맷을 잡는 데 초점을 둡니다. 이는 Django의 ModelForm 사용 방식과 유사합니다.

아래는 DRF Single Model의 기본 구현 예제입니다.

프로젝트 구조

api_pjt/urls.py

1
2
3
4
5
6
7
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/v1/articles/", include("articles.urls")),
]

articles/urls.py

1
2
3
4
5
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = []

articles/views.py

1
2
3
4
5
6
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ArticleSerializer
from .models import Article

# Create your views here.

API 설계

1. Article 목록 조회 (List)

articles/urls.py

1
2
3
4
5
6
7
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("", views.article_list, name="article_list"),
]

articles/views.py

1
2
3
4
5
6
7
8
9
10
11
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ArticleSerializer
from .models import Article

@api_view(["GET"])
def article_list(request):
    articles = Article.objects.all()
    serializer = ArticleSerializer(articles, many=True)
    return Response(serializer.data)

articles/serializers.py

1
2
3
4
5
6
7
from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = "__all__"

Postman 테스트

GET /api/v1/articles/를 호출하여 데이터를 확인합니다.

2. Article 상세 조회 (Detail)

articles/urls.py

1
2
3
4
5
6
7
8
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("", views.article_list, name="article_list"),
    path("<int:pk>/", views.article_detail, name="article_detail"),
]

articles/views.py

1
2
3
4
5
@api_view(["GET"])
def article_detail(request, pk):
    article = get_object_or_404(Article, pk=pk)
    serializer = ArticleSerializer(article)
    return Response(serializer.data)

Postman 테스트

GET /api/v1/articles/<id>/를 호출하여 특정 데이터를 확인합니다.

3. Article 생성 (Create)

데이터 형식

1
2
3
4
{
    "title": "제목",
    "content": "내용"
}

articles/views.py (1차)

1
2
3
4
5
6
7
8
9
10
11
12
@api_view(["GET", "POST"])
def article_list(request):
    if request.method == "GET":
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
    elif request.method == "POST":
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

개선된 코드

articles/views.py (완성)

1
2
3
4
5
6
7
8
9
10
11
12
13
from rest_framework import status

@api_view(["GET", "POST"])
def article_list(request):
    if request.method == "GET":
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
    elif request.method == "POST":
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

4. Article 삭제 (Delete)

articles/views.py

1
2
3
4
5
6
7
8
9
10
@api_view(["GET", "DELETE"])
def article_detail(request, pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "GET":
        serializer = ArticleSerializer(article)
        return Response(serializer.data)
    elif request.method == "DELETE":
        article.delete()
        data = {"delete": f"Article({pk}) is deleted."}
        return Response(data, status=status.HTTP_200_OK)

5. Article 수정 (Update)

DRF의 partial 옵션을 사용하여 일부 필드만 수정할 수 있습니다. 공식 문서를 참고하세요: DRF Partial Updates.

Update 예제

1
2
3
4
5
6
7
8
9
@api_view(["PUT", "PATCH"])
def article_update(request, pk):
    article = get_object_or_404(Article, pk=pk)
    partial = request.method == "PATCH"
    serializer = ArticleSerializer(article, data=request.data, partial=partial)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
This post is licensed under CC BY 4.0 by the author.