본문 바로가기
Programming/Django

[Django] 중첩된 시리얼라이저(Nested Serializers) 완벽 이해하기

by Mandy's 2025. 8. 11.

안녕하세요! Django Rest Framework(DRF)를 사용하다 보면, 시리얼라이저(Serializer)를 마주하게 됩니다. 시리얼라이저는 파이썬 객체를 JSON 같은 데이터 형식으로, 또는 그 반대로 변환해주는 아주 중요한 도구죠.

그런데 때로는 하나의 데이터가 단순한 값이 아니라, 그 안에 또 다른 객체를 포함하는 경우가 있습니다. 예를 들어, 레시피라는 객체가 있고 그 안에 태그(Tag) 목록이 포함되어 있다고 해봅시다. 이때, 태그는 단순한 문자열이 아니라 id와 name을 가진 여러 객체로 구성될 수 있습니다.

이럴 때 사용하는 것이 바로 중첩된 시리얼라이저(Nested Serializers)입니다.


중첩된 시리얼라이저란?

중첩된 시리얼라이저는 시리얼라이저 안에 또 다른 시리얼라이저를 필드로 사용하는 것을 말합니다. 이는 복잡한 객체 관계를 API 응답으로 깔끔하게 표현할 수 있게 해줍니다.

일반적인 API 응답 예시:

{
    "title": "맛있는 스파게티",
    "user": "김코딩",
    "tags": ["점심", "파스타"]
}

위 예시에서는 tags가 단순한 문자열 리스트입니다.

중첩된 시리얼라이저를 사용한 API 응답 예시:

{
    "id": 1,
    "title": "맛있는 스파게티",
    "user": "김코딩",
    "tags": [
        {
            "id": 101,
            "name": "점심"
        },
        {
            "id": 102,
            "name": "파스타"
        }
    ]
}

여기서 tags는 id와 name을 가진 객체들의 리스트입니다. tags 필드 안에 또 다른 객체들이 "중첩"되어 있죠.


코드로는 어떻게 구현할까요?

코드에서는 두 개의 시리얼라이저를 정의한 뒤, 메인 시리얼라이저의 필드로 다른 시리얼라이저를 넣어주면 됩니다.

  1. 태그 시리얼라이저 정의: 먼저 태그 객체(id와 name)를 위한 TagSerializer를 만듭니다.
    from rest_framework import serializers
    from core.models import Tag
    
    class TagSerializer(serializers.ModelSerializer):
        class Meta:
            model = Tag
            fields = ('id', 'name')
    

     

     
     
  2. 레시피 시리얼라이저에 태그 시리얼라이저 중첩: 이제 레시피 시리얼라이저(RecipeSerializer)를 만들면서, tags 필드에 방금 만든 TagSerializer를 연결합니다.
    from rest_framework import serializers
    from core.models import Recipe
    
    # TagSerializer를 불러옵니다.
    from .serializers import TagSerializer
    
    class RecipeSerializer(serializers.ModelSerializer):
        # tags 필드에 TagSerializer를 연결합니다.
        # many=True는 여러 개의 객체를 다룰 때 필요합니다.
        tags = TagSerializer(many=True, read_only=True)
    
        class Meta:
            model = Recipe
            fields = ('id', 'title', 'tags')
    
     
     

위 코드에서 tags = TagSerializer(many=True, read_only=True) 부분이 핵심입니다. tags 필드가 TagSerializer의 기능을 그대로 가져오게 되죠. many=True는 태그가 한 개가 아닌 여러 개일 수 있다는 것을 의미합니다.


주의할 점: 기본적으로 읽기 전용

DRF에서 중첩된 시리얼라이저는 기본적으로 읽기 전용(read-only)입니다.

즉, 위 예시처럼 구현하면 클라이언트에서 레시피를 조회할 때 태그 정보를 함께 볼 수는 있지만, API 요청으로 새로운 레시피를 생성하거나 기존 레시피의 태그 목록을 수정할 수는 없습니다. 만약 수정 기능을 추가하고 싶다면, 시리얼라이저의 create()나 update() 메서드를 오버라이딩하여 직접 로직을 구현해야 합니다.

정리

중첩된 시리얼라이저는 복잡한 데이터 관계를 API 응답으로 구조화할 때 매우 유용합니다. 이를 통해 코드를 더 깔끔하게 유지하고, 클라이언트가 데이터를 더 쉽게 이해하고 사용할 수 있도록 도와줍니다.

다음에는 중첩된 시리얼라이저를 활용해 데이터 수정 기능을 구현하는 방법에 대해 알아보겠습니다!