Django REST Framework - Serializer & API

2025. 3. 10.·학습 주제/Django & Django Rest Framework
 

Serializer

 

 

출처: https://www.codingforentrepreneurs.com/courses/django-rest-framework-2022

Django REST Framework(DRF)의 Serializer는 데이터(모델 인스턴스, QuerySet 등)를 JSON 형식으로 변환(Serialize)하거나, JSON 데이터를 다시 모델 인스턴스로 변환(Deserialize)하는 역할을 합니다.

Serializer와 Deserializer

Serializer

  • 모델 인스턴스나 QuerySet 데이터를 JSON 형식으로 변환
  • 예: API 응답 데이터 생성

Deserializer

  • JSON 데이터를 모델 인스턴스로 변환
  • 예: 클라이언트 요청 데이터를 저장

Serializer 필드 매칭

Serializer는 유효성 검사를 거친 데이터를 기반으로 저장하며, 다음과 같은 방식으로 필드를 정의할 수 있습니다.

from rest_framework import serializers

class QuestionSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    question_text = serializers.CharField(max_length=200)
    pub_date = serializers.DateTimeField(read_only=True)

    def create(self, validated_data):
        return Question.objects.create(**validated_data)
    
    def update(self, instance, validated_data):
        instance.question_text = validated_data.get('question_text', instance.question_text) + '[시리얼라이저에서 업데이트]'
        instance.save()
        return instance

Django Shell에서 Serializer 사용하기

(1) Serialize

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework.renderers import JSONRenderer

# 모델 인스턴스를 Serializer로 변환
q = Question.objects.first()
serializer = QuestionSerializer(q)
serializer.data  # Python Dictionary 형태

# JSON 파일 형식으로 변환
json_str = JSONRenderer().render(serializer.data)
json_str  # JSON 형식의 문자열 출력

(2) Deserialize

import json
from polls_api.serializers import QuestionSerializer

# JSON 문자열을 Python Dictionary로 변환
data = json.loads(json_str)

# Serializer를 사용하여 데이터 검증
serializer = QuestionSerializer(data=data)
serializer.is_valid()  # 유효성 검사
serializer.validated_data  # 유효한 데이터 확인

# 모델 인스턴스 저장 (Create)
new_question = serializer.save()

# Update 활용
update_data = {'question_text': '제목수정'}
serializer = QuestionSerializer(new_question, data=update_data)
serializer.is_valid()
serializer.save()  # 기존 데이터 업데이트

(3) Validation 실패 시 처리

long_text = "abcd" * 300  # 200자를 초과하는 텍스트
invalid_data = {'question_text': long_text}
serializer = QuestionSerializer(data=invalid_data)
serializer.is_valid()  # False 반환
serializer.errors  # 오류 메시지 출력

ModelSerializer 사용하기

기존 Serializer는 필드를 하나씩 지정해야 하지만, ModelSerializer를 사용하면 더 간결하게 정의할 수 있습니다.

from rest_framework import serializers
from polls.models import Question

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ['id', 'question_text', 'pub_date']

ModelSerializer 검증

from polls_api.serializers import QuestionSerializer

serializer = QuestionSerializer(data={'question_text': 'ModelSerializer 예제'})
serializer.is_valid()
serializer.save()
Question.objects.all()  # 저장된 데이터 확인

 

Question 모델 API 구현

 

Django REST Framework 설정

  • 먼저 rest_framework를 설치
  • settings.py의 INSTALLED_APPS에 추가
INSTALLED_APPS = [
    ...
    'rest_framework',
    'polls_api',  # API를 구현할 앱
]

GET 요청: 전체 Question 조회

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from polls.models import Question
from polls_api.serializers import QuestionSerializer

@api_view(['GET'])
def question_list(request):
    questions = Question.objects.all()
    serializer = QuestionSerializer(questions, many=True)
    return Response(serializer.data)

urls.py

from django.urls import path
from .views import question_list

urlpatterns = [
    path('question/', question_list, name='question-list'),
]

Django 프로젝트의 urls.py에도 아래와 같이 포함해야 합니다.

from django.urls import include
path('rest/', include('polls_api.urls')),

POST 요청: Question 생성

views.py 수정

@api_view(['GET', 'POST'])
def question_list(request):
    if request.method == 'GET':
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many=True)
        return Response(serializer.data)
    
    if request.method == 'POST':
        serializer = QuestionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)  # HTTP 201 Created
        return Response(serializer.errors, status=400)  # HTTP 400 Bad Request

개별 Question 조회

views.py

from django.shortcuts import get_object_or_404

@api_view(['GET'])
def question_detail(request, id):
    question = get_object_or_404(Question, pk=id)
    serializer = QuestionSerializer(question)
    return Response(serializer.data)

urls.py

path('question/<int:id>/', question_detail, name='question-detail'),

PUT 요청: Question 수정

views.py

@api_view(['GET', 'PUT'])
def question_detail(request, id):
    question = get_object_or_404(Question, pk=id)
    
    if request.method == 'GET':
        serializer = QuestionSerializer(question)
        return Response(serializer.data)
    
    if request.method == 'PUT':
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=200)  # HTTP 200 OK
        return Response(serializer.errors, status=400)  # HTTP 400 Bad Request

DELETE 요청: Question 삭제

@api_view(['GET', 'PUT', 'DELETE'])
def question_detail(request, id):
    question = get_object_or_404(Question, pk=id)
    
    if request.method == 'DELETE':
        question.delete()
        return Response(status=204)  # HTTP 204 No Content

HTTP 상태 코드

  • 200 OK: 요청이 성공적으로 처리됨
  • 201 CREATED: 새로운 리소스 생성
  • 204 NO CONTENT: 삭제 성공
  • 400 BAD REQUEST: 잘못된 요청
  • 404 NOT FOUND: 리소스를 찾을 수 없음

'학습 주제 > Django & Django Rest Framework' 카테고리의 다른 글

Django REST Framework - User 생성 & 사용자 권한 관리  (0) 2025.03.10
Django REST Framework - Views  (0) 2025.03.10
Django - 예외 처리하기 & Admin  (0) 2025.03.10
Django - 상세 페이지 & 폼 & 커스터마이징  (0) 2025.03.10
Django - 모델 관계 기반 필터링 & 뷰 & 템플릿  (0) 2025.03.10
'학습 주제/Django & Django Rest Framework' 카테고리의 다른 글
  • Django REST Framework - User 생성 & 사용자 권한 관리
  • Django REST Framework - Views
  • Django - 예외 처리하기 & Admin
  • Django - 상세 페이지 & 폼 & 커스터마이징
굥여9
굥여9
9idryd 님의 블로그 입니다.
  • 굥여9
    문과의 개발
    굥여9
  • 전체
    오늘
    어제
    • 분류 전체보기 (114)
      • 학습 주제 (86)
        • 자료구조와 알고리즘 (8)
        • HTML & 웹크롤링 (4)
        • 데이터 시각화 (4)
        • Django & Django Rest Framew.. (11)
        • AWS 클라우드 (6)
        • SQL & 데이터 웨어하우스 (11)
        • 데이터파이프라인과 Airflow (12)
        • Docker & K8S (8)
        • DBT (4)
        • CI & CD (1)
        • 빅데이터 처리와 Spark (12)
        • Kafka & Spark Streaming (5)
        • 보안 엔지니어링 (0)
      • 구름 프로펙트 클라우드 엔지니어링 (0)
        • [Monolithic] 서비스의 기초와 설계 (0)
        • [MSA & EDA] 비동기 전환과 정합성 (0)
        • [Cloud Native] K8s 기반 인프라와 .. (0)
      • 프로그래머스 데브코스 데이터 엔지니어링 (4)
      • 개발 기록 (24)
        • 일일 (24)
        • 주간 (0)
      • 회고 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
굥여9
Django REST Framework - Serializer & API
상단으로

티스토리툴바