본문 바로가기
Python/Django

Django Serialize 심화

by 좌우지간에 2025. 1. 23.
Django REST Framework에서 직렬화와 역직렬화 완벽 이해하기

Django REST Framework에서 직렬화와 역직렬화 완벽 이해하기

목차

  1. 소개
  2. 직렬화와 역직렬화란 무엇인가?
  3. `request.data`의 형태 알아보기
  4. Serializer의 역할과 동작 원리
  5. 직렬화 과정 상세 설명
  6. 역직렬화 과정 상세 설명
  7. 유효성 검사와 에러 처리
  8. 실제 코드로 보는 직렬화와 역직렬화
  9. 자주 하는 실수와 해결 방법
  10. 추가 활용 예제
  11. 결론
  12. 참고 자료

소개

Django REST Framework(DRF)는 Django를 기반으로 한 강력한 API 개발 도구입니다. 이 프레임워크를 사용하면서 직렬화(Serialization)역직렬화(Deserialization)의 개념을 정확히 이해하는 것은 API 서버 개발에 있어서 매우 중요합니다. 이 글에서는 직렬화와 역직렬화가 무엇인지, 왜 필요한지, 그리고 DRF에서 이를 어떻게 구현하는지 자세히 알아보겠습니다.

직렬화와 역직렬화란 무엇인가?

직렬화(Serialization)

  • 정의: 파이썬 객체(예: Django 모델 인스턴스)를 JSON, XML 등과 같은 포맷으로 변환하는 과정입니다.
  • 왜 필요한가?: 클라이언트는 일반적으로 JSON과 같은 포맷을 통해 데이터를 주고받기 때문에 서버 측의 데이터를 이러한 포맷으로 변환해야 합니다.

역직렬화(Deserialization)

  • 정의: 클라이언트로부터 받은 JSON, XML 등의 데이터를 파싱하여 파이썬 객체로 변환하는 과정입니다.
  • 왜 필요한가?: 서버는 클라이언트로부터 데이터를 받아 내부 로직 처리나 데이터베이스 저장을 위해 이를 파이썬 객체로 변환해야 합니다.

왜 중요한가?

  • 데이터 교환: 직렬화와 역직렬화는 서버와 클라이언트 간의 원활한 데이터 교환을 가능하게 합니다.
  • 보안 및 유효성 검사: 역직렬화 과정에서 입력된 데이터의 유효성을 검증하여 보안성을 높일 수 있습니다.

`request.data`의 형태 알아보기

`request.data`는 클라이언트로부터 전달된 요청 데이터를 파싱하여 제공하는 속성입니다. 이 데이터의 형태는 요청의 `Content-Type`에 따라 달라집니다.

  • JSON 데이터의 경우 (`Content-Type: application/json`):
    • `request.data`는 JSON 데이터를 파싱한 파이썬의 `dict` 객체입니다.
  • 폼 데이터의 경우 (`Content-Type: multipart/form-data` 또는 `application/x-www-form-urlencoded`):
    • `request.data`는 Django의 `QueryDict` 객체이지만, DRF에서는 이를 일반 `dict`처럼 사용할 수 있도록 처리해줍니다.

따라서, `request.data`는 보통 파이썬의 `dict` 객체로 생각하고 사용하면 됩니다.

Serializer의 역할과 동작 원리

Serializer의 역할

Serializer는 DRF에서 직렬화와 역직렬화 모두를 담당하는 핵심 구성 요소입니다.

  1. 직렬화(Serialization):
    • 파이썬 객체를 JSON 등의 포맷으로 변환하여 클라이언트에게 전달합니다.
  2. 역직렬화(Deserialization):
    • 클라이언트로부터 받은 데이터를 파싱하여 파이썬 객체로 변환하고, 유효성 검사를 수행합니다.

Serializer의 동작 원리

  • 필드 매핑: Serializer는 모델의 필드와 입력 데이터의 키를 매핑합니다.
  • 유효성 검사: 각 필드에 대한 유효성 검사를 수행하고, 전체 데이터에 대한 검증도 가능합니다.
  • 데이터 변환: 직렬화 시 모델 인스턴스를 `dict`로 변환하고, 역직렬화 시 입력 데이터를 `validated_data`로 변환합니다.
  • 데이터 저장: `save()` 메서드를 통해 데이터베이스에 인스턴스를 생성하거나 업데이트합니다.

예시 코드:

from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'title', 'content', 'author']

직렬화 과정 상세 설명

1. 모델 인스턴스 획득

article = Article.objects.get(pk=pk)

- 데이터베이스에서 원하는 객체를 가져옵니다.

2. Serializer를 통한 직렬화

serializer = ArticleSerializer(article)

- 모델 인스턴스를 Serializer에 전달하여 파이썬의 `dict` 형태로 변환합니다.

- `serializer.data`에 직렬화된 데이터가 저장됩니다.

3. 응답 생성

from rest_framework.response import Response

return Response(serializer.data)

- `Response` 객체를 사용하여 JSON 응답을 생성합니다.

- DRF는 내부적으로 `renderer`를 사용하여 `serializer.data`를 JSON으로 변환합니다.

정리:

  • 직렬화된 데이터는 JSON이 아닌 `dict` 형태입니다.
  • `Response` 객체를 통해 클라이언트는 JSON 응답을 받게 됩니다.

역직렬화 과정 상세 설명

1. 입력 데이터 수신

data = request.data

- 클라이언트로부터 전달된 데이터를 받습니다.

2. Serializer를 통한 역직렬화

serializer = ArticleSerializer(article, data=data, partial=True)

- 입력 데이터를 Serializer에 전달하여 역직렬화를 수행합니다.

- `partial=True`는 일부 필드만 업데이트할 수 있도록 허용합니다.

3. 유효성 검사

if serializer.is_valid(raise_exception=True):

- `is_valid()` 메서드를 호출하여 데이터의 유효성을 검사합니다.

- 유효한 데이터는 `serializer.validated_data`에 저장됩니다.

4. 데이터 저장

serializer.save()

- `validated_data`를 사용하여 데이터베이스에 저장하거나 업데이트합니다.

- 인스턴스 생성 시 `create()` 메서드, 업데이트 시 `update()` 메서드를 내부적으로 호출합니다.

5. 응답 생성

return Response(serializer.data)

- 저장된 데이터를 직렬화하여 응답합니다.

정리:

  • 역직렬화된 데이터는 `serializer.validated_data`에 `OrderedDict` 형태로 저장됩니다.
  • `save()` 메서드를 통해 데이터베이스에 변경 사항이 반영됩니다.

유효성 검사와 에러 처리

유효성 검사

  • 필드 수준 유효성 검사: 각 필드마다 `validators`를 통해 검증합니다.
  • 객체 수준 유효성 검사: `validate()` 메서드를 오버라이딩하여 객체 전체에 대한 검증을 수행합니다.

예시 코드:

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'
    
    def validate_title(self, value):
        if '금지어' in value:
            raise serializers.ValidationError("제목에 금지어가 포함되어 있습니다.")
        return value

에러 처리

  • `is_valid(raise_exception=True)`를 사용하면 유효성 검사 실패 시 자동으로 `ValidationError`가 발생하고, DRF는 적절한 에러 응답을 생성합니다.
if serializer.is_valid(raise_exception=True):
    serializer.save()
else:
    return Response(serializer.errors, status=400)

실제 코드로 보는 직렬화와 역직렬화

직렬화 예제

from rest_framework.views import APIView

class ArticleDetailView(APIView):
    def get(self, request, pk):
        article = Article.objects.get(pk=pk)
        serializer = ArticleSerializer(article)
        return Response(serializer.data)

설명:

  • `GET` 요청 시 `Article` 인스턴스를 가져와 Serializer를 통해 직렬화합니다.
  • 직렬화된 데이터를 `Response`를 통해 클라이언트에게 반환합니다.

역직렬화 예제

class ArticleUpdateView(APIView):
    def put(self, request, pk):
        article = Article.objects.get(pk=pk)
        serializer = ArticleSerializer(article, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

설명:

  • `PUT` 요청 시 클라이언트로부터 입력된 데이터를 받아 Serializer에 전달합니다.
  • 유효성 검사를 통과하면 `save()` 메서드로 데이터베이스를 업데이트합니다.
  • 업데이트된 데이터를 직렬화하여 응답합니다.

자주 하는 실수와 해결 방법

1. `serializer.data`를 JSON이라고 착각하는 경우

  • 실수: 직렬화된 데이터가 이미 JSON이라고 생각하여 추가 처리 없이 사용함.
  • 해결 방법: `serializer.data`는 `dict` 형태이며, `Response` 객체를 사용하여 JSON으로 변환해야 합니다.

2. 유효성 검사를 누락하는 경우

  • 실수: `is_valid()` 메서드를 호출하지 않고 `save()`를 호출함.
  • 해결 방법: 항상 `is_valid()`를 통해 유효성 검사를 수행한 후 `save()`를 호출해야 합니다.

3. 역직렬화 시 `instance`를 전달하지 않는 경우

  • 실수: 업데이트 시 기존 인스턴스를 `Serializer`에 전달하지 않음.
  • 해결 방법: 업데이트 시에는 `Serializer`를 생성할 때 `instance`와 `data`를 모두 전달해야 합니다.

추가 활용 예제

1. 토큰 인증과의 연계

- 사용자 인증 시 토큰을 발급하고 직렬화를 통해 응답합니다.

2. 파일 업로드 처리

- 파일을 포함한 폼 데이터를 처리할 때도 Serializer를 사용하여 역직렬화합니다.

3. Nested Serializer 활용

- 관계형 데이터를 처리할 때 중첩 Serializer를 사용하여 복잡한 데이터를 직렬화하고 역직렬화할 수 있습니다.

예시 코드:

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

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

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

결론

Django REST Framework에서 직렬화역직렬화는 서버와 클라이언트 간의 원활한 데이터 교환을 가능하게 하는 핵심 요소입니다.

  • `request.data`는 일반적으로 파이썬의 `dict` 형태이며, Serializer를 통해 직렬화와 역직렬화를 수행합니다.
  • 직렬화된 데이터는 JSON이 아닌 `dict`이고, `Response` 객체를 통해 클라이언트에게 JSON 형식으로 전달됩니다.
  • 역직렬화 과정에서 유효성 검사를 통과한 데이터는 `serializer.validated_data`에 저장되며, `save()` 메서드를 통해 데이터베이스에 반영됩니다.
  • Serializer는 내부적으로 데이터 변환과 저장 로직을 처리하므로, 개발자는 복잡한 데이터 처리 로직에 집중할 수 있습니다.

참고 자료

'Python > Django' 카테고리의 다른 글

Django User정보 넣기  (0) 2025.01.22
DRF(Serializer)  (1) 2025.01.21
Django 에서 commit  (0) 2025.01.20
웹보안을 위해 쿠키, 세션, 해시 그리고 JWT (Django 관점)  (1) 2025.01.17
DRF학습전 API, RESTful API 미리보기  (1) 2025.01.16