DRF Tutorial

DRF Tutorial 1: Serialization 1

waterclean101 2023. 2. 13. 17:45

Django REST framework 문서의 튜토리얼을 따라하면서(번역하면서) DRF에 관한 내용들을 적을 예정


가상환경 세팅

새로운 프로젝트를 시작하기 전 새 가상환경을 만드는 것으로 시작한다. 이것은 작업 중인 다른 프로젝트와 잘 분리시키기 위함이다.

python3 -m venv env
source env/bin/activate

위의 코드로 가상환경을 생성하고 가상환경 안으로 진입하였다. 그 후 필요한 패키지들을 설치한다.

pip install django
pip install djangorestframework
pip install pygments  # We'll be using this for the code highlighting

 

프로젝트의 시작

작업할 프로젝트를 만들어준다. 프로젝트의 이름은 'tutorial'로 했다. 

cd ~
django-admin startproject tutorial
cd tutorial

프로젝트를 만들고 cd tutorial 명령으로 프로젝트 안에 들어갔으면 간단한 웹 API를 생성할 때 쓸 앱을 만들어준다. 

python manage.py startapp snippets

아까 설치한 rest_framework 앱과 snippets라는 새로운 앱을 settings.py 안의 INSTALLED_APPS에 등록한다.

# tutorial/settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
    'snippets',
]

 

모델 만들기

코드 조각을 저장하는 데 사용되는 간단한 스니펫 모델을 만드는 것부터 시작한다.

# 스니펫(snippet)은 재사용 가능한 소스 코드, 기계어, 텍스트의 작은 부분을 일컫는 프로그래밍 용어

# snippets/models.py

from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles

LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)

    class Meta:
        ordering = ['created']

스니펫 모델을 마이그레이션 해준다. 

python manage.py makemigrations snippets
python manage.py migrate snippets

 

시리얼라이저 만들기

웹 API를 시작하기 위해 가장 먼저 해야 할 일은 스니펫 인스턴스를 json과 같은 표현으로 직렬화 및 역직렬화하는 방법을 제공하는 것이다. 이를 위해 Django의 forms과 매우 유사하게 작동하는  'serializers'를 선언하면 된다. snippets 디렉터리에 serializers.py라는 이름의 파일을 생성하고 아래 코드를 적는다.

# snippets/serializers.py

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES


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

시리얼라이저 클래스의 첫 부분은 시리얼라이즈/디시리얼라이즈 될 필드들을 정의한다.  create()와 update() 메소드는  serializer.save()를 호출할 때 완전한 인스턴스가 생성되거나 수정되는 방식을 정의한다.

시리얼라이저 클래스는 장고의 Form 클래스와 매우 유사하고 다양한 required, max_length and default 같은 다양한 필드에 유사한 유효성 검사 플래그를 포함한다.

필드 플래그는 HTML을 렌더링 할 때와 같이 특정 상황에서 시리얼라이져가 표시되는 방식을 제어할 수도 있다. 위의 {'base_template': 'textarea.html'} 플래그는  Django Form 클래스에서 widget=widgets.Textarea를 사용하는 것과 동일하다. 이 플래그는 튜토리얼의 뒷부분에서 살펴볼 것처럼 탐색 가능한 API가 표시되는 방식을 제어하는 데 특히 유용하다.

ModelSerializer 클래스를 사용하면 시간을 절약할 수도 있지만, 이것은 나중에 살펴보고 지금은 시리얼라이저 정의를 명시적으로 유지하겠다.

 


시리얼라이저 더 알아보기 

시리얼라이저란 무엇이고 어떤 역할을 하는가 쉽게 예시를 들어 설명해본다.

시리얼라이저를 사용하지 않고 모델의 관리자인 objects 객체로 데이터베이스에서 데이터를 직접 꺼내와 JsonResponse로 전달한다면 

example

QuerySet JSON serializable 하지 않다는 에러를 보게 된다. 

QuerySet 그 자체는 serializable 하지 않다. 즉, Json이 될 수 없다. Python 객체를 JSON으로서 주려고 하는데, 그 변환이 일어나지 않는 것이다. 따라서 Python 객체를 JSON으로 번역해줄 무언가가 필요하고 그 '무언가'의 역할을 serializer가 해준다.

 


 

'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 2  (0) 2023.02.14