Django

Serializer 활용하기

zhelddustmq 2024. 8. 29. 21:55

1. Article에 Comment 추가하기 : 모델 사이에 참조 관계가 있다면 해당 필드를 포함하거나 중첩할 수 있음

 

결국 우리가 조작해줘야할 것: Serializer

  • 현재 Article → Comments 접근이 필요 == 역참조
  • 역참조시 사용할 수 있는 comment_set 이 있으나 우리는 comments 로 명명
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 라는 기존에 존재하는 매니저 이름으로 된 필드를 다시 override 하는데 표현 방식은 CommentSerializer 를 사용

 

2. 응답 구조만 변경하기: 댓글 조회에서 article 로 내려오는 필드 삭제

공식문서: https://www.django-rest-framework.org/api-guide/fields/#custom-fields

to_representation()

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")
        return ret
  • Serialization이후 보여지는 결과에 대해 자동으로 내부적으로 불리는 함수
  • 이 메서드를 override 하여 커스텀 형식으로 변경 가능

3.상속 활용하기:시글 목록 조회에서도 댓글 관련 필드들이 내려오고 있는데, 이건 상세 조회에서만 나오게 됨.

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)
class ArticleListAPIView(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 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)

'Django' 카테고리의 다른 글

Django ORM (심화)  (0) 2024.08.30
JSON Web Token, JWT  (0) 2024.08.30
Relationship과 DRF(with. particular seed)  (0) 2024.08.29
DRF CBV  (0) 2024.08.29
DRF와 Postman (GET, PUT, DELETE, POST)  (0) 2024.08.29