기본 구조: 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)
Serializer fields - Django REST framework
www.django-rest-framework.org
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 |