Django REST Framework (DRF) Serializer 활용하기
Django REST Framework의 Serializer를 활용한 데이터 직렬화 및 커스터마이징 가이드.
Django REST Framework (DRF) Serializer 활용하기
Django REST Framework(DRF)의 Serializer
는 데이터 직렬화 및 역직렬화, 유효성 검증, 데이터 구조 커스터마이징을 위한 핵심 도구입니다.
1. Serializer
의 기본 개념
Serializer
는 다음과 같은 역할을 합니다:
- 직렬화: 데이터베이스 모델 데이터를 JSON으로 변환하여 클라이언트로 전달.
- 역직렬화: 클라이언트에서 전달된 JSON 데이터를 파이썬 객체로 변환.
- 유효성 검사: 데이터의 형식 및 조건을 검증.
1
2
3
4
5
6
from rest_framework import serializers
class ArticleSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
created_at = serializers.DateTimeField(read_only=True)
2. 주요 Serializer 필드
Django REST Framework에서 제공하는 주요 Serializer 필드는 데이터를 변환하거나 검증하는 데 유용합니다.
2.1 기본 필드
CharField
: 문자열 데이터를 처리합니다.IntegerField
: 정수 데이터를 처리합니다.BooleanField
: Boolean 데이터를 처리합니다.EmailField
: 이메일 형식의 문자열을 처리하고 검증합니다.DateField
: 날짜 데이터를 처리합니다.DateTimeField
: 날짜 및 시간 데이터를 처리합니다.
1
2
3
4
class BasicSerializer(serializers.Serializer):
name = serializers.CharField(max_length=50)
age = serializers.IntegerField()
is_active = serializers.BooleanField()
2.2 관계 필드
PrimaryKeyRelatedField
: 외래 키 관계를 ID로 처리합니다.StringRelatedField
: 외래 키 객체의 문자열 표현을 반환합니다.SlugRelatedField
: 특정 필드(slug) 값을 기준으로 관계를 처리합니다.HyperlinkedRelatedField
: 객체를 URL로 직렬화합니다.
1
2
3
4
5
6
class RelatedSerializer(serializers.ModelSerializer):
related_field = serializers.StringRelatedField()
class Meta:
model = SomeModel
fields = ['id', 'related_field']
2.3 커스텀 필드
SerializerMethodField
: 메서드를 사용해 직렬화 데이터를 생성합니다.
1
2
3
4
5
6
7
8
9
class CustomSerializer(serializers.ModelSerializer):
custom_field = serializers.SerializerMethodField()
class Meta:
model = SomeModel
fields = ['id', 'custom_field']
def get_custom_field(self, obj):
return "Custom Value"
2.4 필드 옵션
read_only
: 필드가 읽기 전용임을 명시합니다.write_only
: 필드가 쓰기 전용임을 명시합니다.required
: 필드가 필수인지 여부를 설정합니다.default
: 필드의 기본값을 설정합니다.validators
: 커스텀 검증 로직을 추가할 수 있습니다.
1
2
3
class OptionSerializer(serializers.Serializer):
name = serializers.CharField(max_length=50, required=True, default="No Name")
email = serializers.EmailField(validators=[custom_validator])
3. 상황별 Serializer
활용하기
3.1 Article에 Comment 추가하기
Article
모델에서 관련된 Comment
모델 데이터를 포함하려면 중첩 관계(Nested Relationships)를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from rest_framework import serializers
from .models import Article, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ("article",)
class ArticleSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True, read_only=True)
class Meta:
model = Article
fields = "__all__"
여기서 comments
필드는 CommentSerializer
를 사용해 데이터를 표현합니다. many=True
로 설정하여 여러 개의 댓글을 처리할 수 있도록 합니다.
3.2 댓글 수 필드 추가하기
클라이언트에서 댓글 수를 표시해야 할 때, 추가 필드를 정의하여 제공할 수 있습니다.
1
2
3
4
5
6
7
class ArticleSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True, read_only=True)
comments_count = serializers.IntegerField(source="comments.count", read_only=True)
class Meta:
model = Article
fields = "__all__"
source
속성: 필드의 값을 가져오기 위해 사용.comments.count
를 사용하여 댓글 개수를 반환합니다.read_only=True
: 클라이언트가 이 필드를 수정하지 못하도록 설정합니다.
3.3 커스텀 데이터 추가하기: SerializerMethodField
동적인 데이터를 추가하려면 SerializerMethodField
를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
days_since_joined = serializers.SerializerMethodField()
class Meta:
model = User
fields = '__all__'
def get_days_since_joined(self, obj):
return (now() - obj.date_joined).days
get_<field_name>
메서드: 커스텀 데이터를 계산하여 반환합니다.
3.4 응답 구조 변경하기: to_representation
to_representation
메서드를 오버라이드하여 응답 데이터를 원하는 형태로 커스터마이징할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ("article",)
def to_representation(self, instance):
ret = super().to_representation(instance)
ret.pop("article") # 'article' 필드 제거
return ret
to_representation
은 직렬화 후 데이터를 수정할 수 있는 강력한 도구입니다.
3.5 Serializer
상속 활용하기
Serializer
상속을 통해 기본 구조를 재사용하고, 상세 조회에서만 특정 필드를 추가하거나 수정할 수 있습니다.
serializers.py
1
2
3
4
5
6
7
8
9
10
11
from rest_framework import serializers
from .models import Article, Comment
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = "__all__"
class ArticleDetailSerializer(ArticleSerializer):
comments = CommentSerializer(many=True, read_only=True)
comments_count = serializers.IntegerField(source="comments.count", read_only=True)
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.status import HTTP_201_CREATED
from django.shortcuts import get_object_or_404
from .models import Article
from .serializers import ArticleSerializer, ArticleDetailSerializer
class ArticleListCreateAPIView(APIView):
def get(self, request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request):
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=HTTP_201_CREATED)
class ArticleDetailAPIView(APIView):
def get_object(self, pk):
return get_object_or_404(Article, pk=pk)
def get(self, request, pk):
article = self.get_object(pk)
serializer = ArticleDetailSerializer(article)
return Response(serializer.data)
def put(self, request, pk):
article = self.get_object(pk)
serializer = ArticleDetailSerializer(article, data=request.data, partial=True)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data)
이 방식으로 게시글 목록과 상세 조회에서 서로 다른 직렬화 구조를 제공합니다.
This post is licensed under CC BY 4.0 by the author.