DRF Tutorial

DRF Tutorial 1: Serialization 2

waterclean101 2023. 2. 14. 10:55

시리얼라이저로 작업하기

시리얼라이저와 친숙해지기 위해 Django 셸을 열어서 작업해보자. 

python manage.py shell

작업할 코드 스니펫을 몇 가지 만들어보자.

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

snippet = Snippet(code='foo = "bar"\n')
snippet.save()

snippet = Snippet(code='print("hello, world")\n')
snippet.save()

# 콘솔에 위와 같이 작성

 

이제 몇 가지 스니펫 인스턴스를 만들었다. 만든 인스턴스 중 하나를 직렬화하는 것을 살펴보겠다.

serializer = SnippetSerializer(snippet)
serializer.data
# {'id': 2, 'title': '', 'code': 'print("hello, world")\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

 

이 시점에서 모델 인스턴스를 Python 네이티브 데이터 타입으로 변환했다. 직렬화 프로세스를 마무리하기 위해 데이터를 json으로 렌더링해준다.

content = JSONRenderer().render(serializer.data)
content
# b'{"id": 2, "title": "", "code": "print(\\"hello, world\\")\\n", "linenos": false, "language": "python", "style": "friendly"}'

 

역직렬화도 비슷하다. 먼저 스트림이란 변수를 파이썬 기본 데이터 유형으로 파싱해주고 이 네이티브 데이터타입을 완전히 채워진 객체 인스턴스로 복원한다.

import io

stream = io.BytesIO(content)
data = JSONParser().parse(stream)
serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
serializer.save()
# <Snippet: Snippet object>

 

모델 인스턴스 대신 쿼리 집합을 직렬화할 수도 있다. 이렇게 하려면 serializer 인수에 many=True 플래그를 추가하기만 하면 된다.

serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print("hello, world")'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

 

모델 시리얼라이저 사용하기

SnippetSerializer 클래스는 스니펫 모델에도 포함된 많은 정보를 복제하고 있다. 코드를 좀 더 간결하게 하면 좋을 것이다.

Django가 Form 클래스와 ModelForm 클래스를 모두 제공하는 것과 같은 방식으로 REST 프레임워크에는 Serializer 클래스와 ModelSerializer 클래스를 모두 제공한다.

ModelSerializer 클래스를 사용하여 시리얼라이저를 리팩토링하는 방법을 살펴볼 것이다. snippets/serializers.py 파일을 다시 열고 SnippetSerializer 클래스를 다음과 같이 바꾸자.

# snippets/serializers.py


class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
      

'''
class SnippetSerializer(serializers.Serializer):

    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    code = serializers.CharField(style={'base_template':'textarea.html'})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')

    def create(self, validated_data):
        """
        Create and return a new 'Snippet' instance, given the validated data.
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing 'Snippet' instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.linenos = validated_data.get('linenos', instance.linenos)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        instance.save()
        return instance
'''

 

시리얼라이저의 한 가지 좋은 속성은 시리얼라이저 인스턴스의 모든 필드를 검사할 수 있다는 것이다. 파이썬 manage.py 셸로 Django 셸을 열고 다음을 써보자.

from snippets.serializers import SnippetSerializer
serializer = SnippetSerializer()
print(repr(serializer))
# SnippetSerializer():
#    id = IntegerField(label='ID', read_only=True)
#    title = CharField(allow_blank=True, max_length=100, required=False)
#    code = CharField(style={'base_template': 'textarea.html'})
#    linenos = BooleanField(required=False)
#    language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
#    style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...

 

ModelSerializer 클래스는 특별히 마법 같은 일을 하는 것이 아니라 단순히 시리얼라이저 클래스를 만들기 위한 지름길이라는 점을 기억하자

  • 자동으로 결정된 필드 집합.
  • create() 및 update() 메서드에 대한 간단한 기본 구현

 

'DRF Tutorial' 카테고리의 다른 글

DRF Tutorial 3: Class-based Views  (0) 2023.02.14
DRF Tutorial 2: Requests and Responses 2  (0) 2023.02.14
DRF Tutorial 2: Requests and Responses 1  (0) 2023.02.14
DRF Tutorial 1: Serialization 3  (0) 2023.02.14
DRF Tutorial 1: Serialization 1  (0) 2023.02.13