Nested Relationships

유정원·2024년 8월 30일

python

목록 보기
10/21

Nested Relationships는 Django REST Framework(DRF)에서 시리얼라이저(Serializer)를 사용하여 모델 간의 관계를 처리할 때 중첩된 형태로 데이터를 직렬화하거나 역직렬화하는 것을 의미합니다. 이를 통해 관련된 객체들을 한 번에 처리할 수 있으며, 특히 부모-자식 관계와 같은 계층적 데이터 구조를 다룰 때 유용합니다.

예시 시나리오

예를 들어, 블로그 포스트와 그에 대한 댓글이 있는 경우를 생각해 봅시다. 각 포스트는 여러 댓글을 가질 수 있으며, 이러한 관계를 처리하기 위해 Nested Relationships을 사용할 수 있습니다.

모델 정의

from django.db import models

class Comment(models.Model):
    post = models.ForeignKey('Post', related_name='comments', on_delete=models.CASCADE)
    author = models.CharField(max_length=100)
    content = models.TextField()

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

1. Nested Relationships - 직렬화

부모 객체(Post)와 자식 객체(Comment)를 함께 직렬화하려는 경우, CommentSerializerPostSerializer 내부에 중첩(nested)하여 사용할 수 있습니다.

from rest_framework import serializers

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['id', 'author', 'content']

class PostSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'comments']

동작 설명

  • CommentSerializer: 댓글(Comment) 모델을 위한 시리얼라이저입니다.
  • PostSerializer: 포스트(Post) 모델을 위한 시리얼라이저이며, comments 필드를 통해 연결된 모든 댓글을 중첩된 형태로 직렬화합니다. many=True는 여러 개의 댓글이 있을 수 있음을 나타냅니다.
  • read_only=True: 댓글 필드가 읽기 전용임을 의미하며, 클라이언트가 포스트를 생성할 때는 댓글 데이터를 포함하지 않아도 된다는 의미입니다.

2. Nested Relationships - 역직렬화

포스트를 생성하거나 업데이트할 때, 관련된 댓글도 함께 처리해야 하는 경우가 있습니다. 이를 위해 댓글 데이터를 직접 제공할 수 있도록 시리얼라이저를 구성할 수 있습니다.

class PostSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'comments']

    def create(self, validated_data):
        comments_data = validated_data.pop('comments')
        post = Post.objects.create(**validated_data)
        for comment_data in comments_data:
            Comment.objects.create(post=post, **comment_data)
        return post

    def update(self, instance, validated_data):
        comments_data = validated_data.pop('comments')
        instance.title = validated_data.get('title', instance.title)
        instance.content = validated_data.get('content', instance.content)
        instance.save()

        # 댓글 업데이트 또는 생성 로직 (여기선 간단하게 구현)
        instance.comments.all().delete()
        for comment_data in comments_data:
            Comment.objects.create(post=instance, **comment_data)

        return instance

동작 설명

  • create 메서드: comments 데이터를 분리해 처리한 후, 포스트를 생성하고 관련된 댓글들을 각각 생성합니다.
  • update 메서드: 기존 포스트를 업데이트하면서, 관련된 댓글을 모두 삭제한 후 새롭게 제공된 댓글 데이터를 추가합니다. (필요에 따라 더 정교하게 구현할 수 있습니다.)

3. Nested Relationships - 사용 예시

POST 요청을 통해 새 포스트와 관련 댓글을 한 번에 생성할 수 있습니다.

요청 데이터 예시:

{
    "title": "My first post",
    "content": "This is the content of my first post.",
    "comments": [
        {
            "author": "Alice",
            "content": "Great post!"
        },
        {
            "author": "Bob",
            "content": "Thanks for sharing."
        }
    ]
}

결과:

위 데이터로 POST 요청을 보내면, 포스트와 그에 연관된 댓글들이 한 번에 데이터베이스에 저장됩니다.

요약

  • Nested Relationships은 DRF에서 부모-자식 관계와 같은 계층적 데이터 구조를 직렬화 및 역직렬화할 때 사용됩니다.
  • 시리얼라이저를 중첩하여 복잡한 관계형 데이터를 쉽게 처리할 수 있으며, 데이터의 생성 및 업데이트도 손쉽게 관리할 수 있습니다.
  • 이를 통해 클라이언트가 필요한 데이터 구조를 한 번의 API 요청으로 처리할 수 있도록 도와줍니다.

0개의 댓글