∟ Framework/∟ DRF

DRF Serializer 활용

최 수빈 2025. 3. 30. 03:34

 

기본 구조: Article에 Comment 추가하기

 

게시글 상세 조회 시, 관련 댓글도 함께 응답으로 내려주기

#articles/serializers.py
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__"

 

Nested Relationships

comments 필드를 override하여 CommentSerializer로 중첩 표현

reverse relationship(역참조): article.comments.all()  comments 필드에 자동 할당

 

 

커스텀 필드 추가하기: 댓글 수 보여주기

 

프론트에서 직접 댓글 개수를 세지 않아도 되도록, comments_count 필드 추가

# articles/serializers.py
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"를 이용하여 queryset 메서드 연결

IntegerField read_only=True 설정으로 조회 전용 처리

 

 

SerializerMethodField: 사용자 가입 후 일수 계산하기

 

from django.utils.timezone import now
from rest_framework import serializers
from django.contrib.auth.models import User

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

 

SerializerMethodField는 커스텀 계산 로직이 필요한 경우 사용

메서드명은 get_<필드명> 형식으로 작성

 

 

응답 필드에서 특정 데이터 제거하기

 

Comment 응답에서 article 필드 제거

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = "__all__"
        read_only_fields = ("article",)

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        rep.pop("article", None)
        return rep

 

to_representation()을 override하여 반환되는 응답 구조 조작

모델/DB 구조는 유지하면서, 출력에만 영향

 

상세 조회와 목록 조회를 구분해서 처리하기 (상속)

 

Article 목록 조회에는 댓글 관련 필드 미포함

Article 상세 조회에만 comments, comments_count 포함

 

# articles/serializers.py
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)

 

# articles/views.py
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=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 delete(self, request, pk):
        article = self.get_object(pk)
        article.delete()
        return Response(
            {"delete": f"Article({pk}) is deleted."}, status=status.HTTP_200_OK
        )

    def put(self, request, pk):
        article = self.get_object(pk)
        serializer = ArticleDetailSerializer(article, data=request.data, partial=False)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

    def patch(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)

게시글 상세조회 시 보이는 댓글과 comments_count
제거된 Article 필드



 

Serializer Method Field

 

Serializer fields - Django REST framework

 

www.django-rest-framework.org

to_representation

 

Serializers - Django REST framework

 

www.django-rest-framework.org

 

 

'∟ Framework > ∟ DRF' 카테고리의 다른 글

Django ORM(Object Relational Mapping) 활용  (0) 2025.03.31
Token Auth with JWT  (0) 2025.03.30
DRF models with relationship CRUD API 구현  (0) 2025.03.30
Class Based View (CBV)  (0) 2025.03.29
DRF Single Model CRUD API 구현  (0) 2025.03.29