1. Hello World 코드 설명

# (수정) 추후 설명하는 그림을 첨부할 예정입니다.

GET 127.0.0.1:8000/api/hello/

 

지난 시간에 해당 주소로 요청을 보내면 hello world를 print하는 api를 만들었습니다.

각 단계를 다시 따라가보며 세부적인 내용을 살펴보겠습니다.

 

첫번째 단계는 views.py를 작성하는 것입니다.

현재 사용하고 있는 view의 구조는 함수 기반 뷰, 이른바 FBV 입니다.

# api/views.py

from rest_framework.response import Response
from rest_framework.decorators import api_view

# Create your views here.
@api_view(['GET']) # 해당 함수 view에서 처리할 http 메소드
def HelloAPI(request):
    return Response("hello world!") # http response 형태로 return

 

views.py에서 다룬 내용은 그냥 Django에서 다룬 것과 크게 다를 것 없이,

요청을 받아 해당 요청에 대한 응답을 제공하는 기능을 합니다.

오늘 배우게 될 serializer와 함께 하면 어떻게 할 수 있는지 이따 알아보겠습니다.

 

그 다음은 api/urls.py 입니다.

# api/urls.py

from django.urls import path, include
from .views import HelloAPI

urlpatterns = [
    path("hello/", HelloAPI),
]

크게 특별할 것 없이 view에 있는 HelloAPI를 가져와 url로 할당시켰습니다.

path 사용을 권장한다는 것을 지난 시간에 말씀드렸습니다.


2. Serializer?

Serializer는 Django Rest Framework에서 나온 새로운 요소입니다.

사전적 의미는 직렬화 하는 무언가 정도로 볼 수 있습니다.

 

직렬화라는 말이 와닿지 않는데,

이는 간단하게 파이썬 데이터를 JSON 타입의 데이터로 변환해준다 정도로 생각하시면 됩니다.

 

기본적으로 웹에서 통신을 할 때, 즉 데이터를 주고 받을 때는 어느 정도 정해진 포맷이 있습니다.

대표적인 타입이 JSON이나 XML인데, 대부분의 REST API에서는 JSON으로 주고 받기 때문에

우리는 그냥 JSON만 잘 알고 있으면 됩니다:)

 

정확한 의미의 직렬화는 Django 프로젝트에서 내가 만든 모델로부터 뽑은 queryset,

즉 모델 인스턴스를 JSON 타입으로 바꾸는 것입니다.

 

기존 일반적인 Django에서의 폼과 같은 개념이라고 비유하는 경우가 있는데,

저는 그냥 Django 모델을 JSON으로 변환하기 위한 모양 틀 정도로 이해하고 있고 그게 제일 깔끔한 것 같습니다!

간단한 코드로 예를 들어보겠습니다.(게시판 프로젝트 코드가 아닙니다)

# test/models.py
from django.db import models
# 설명만을 위한 모델로, 상당히 대충 작성 되었습니다:)
class Person(models.Model):
    id = models.IntegerField()
    name = models.CharField()
    phone = models.CharField()
    addr = models.CharField()
    email = models.CharField()
# test/serializers.py
from rest_framework import serializers
from .models import Person

# ModelSerializer 뒤에서 설명합니다.
class BasePersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('id', 'name', 'phone', 'addr')

위에서 보시면 Person이라는 모델을 models.py에 만들고,

BasePersonSerializer라는 시리얼라이저를 serializers.py에 만들었습니다.(앱 내에 파일을 생성하셔야 합니다)

 

이게 어떤 뜻이냐면,

"내가 만든 Person이라는 모델에서 데이터를 뽑아서 응답으로 보낼텐데,

응답의 형태 중 하나인 Base 형태를 BasePersonSerializer라고 정의할게!" 라는 뜻입니다.

 

자세히 보시면 모델에는 email도 정의되어있는데 Base의 fields에는 email이 없습니다.

이는 개발자가 정의한 Base 형태에는 email이 없다는 뜻이죠.

그러면 사람의 이메일 정보를 요청할 때 쓸 수 있는 시리얼라이저는 어떻게 만들 수 있을까요?

# test/serializers.py
from rest_framework import serializers
from .models import Person

# ModelSerializer 뒤에서 설명합니다.
class EmailPersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('id', 'email')

이렇게 만들어 볼 수 있습니다.

 

이제 우리는 한 가지 깨달음을 얻을 수 있습니다.

시리얼라이저는 응답으로 보낼 데이터의 형태를 정해주는 하나의 틀과 같구나!


3. Serializer - View 연결하기

여기까지 잘 이해되셨다면 이후 단계에서는 더 잘 이해될 것입니다.

이제는 그럼 views.py에 실제로 시리얼라이저가 어떻게 사용되는지 알려드리겠습니다.

# test/views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Person
from .serializers import BasePersonSerializer, EmailPersonSerializer

@api_view(['GET'])
def PersonAPI(request, id):
    now_person = Person.object.get(id=id)
    serializer = BasePersonSerializer(now_person)
    return Response(serializer.data)
# => id=1에 대해 리턴된 Response: {'id': 1, 'name': '태뽕', 'phone': '01012345678', 'addr': '주소주소'}

@api_view(['GET'])
def EmailAPI(request, id):
    now_person = Person.object.get(id=id)
    serializer = EmailPersonSerializer(now_person)
    return Response(serializer.data)
# => id=1에 대해 리턴된 Response: {'id': 1, 'email': 'email@email.com'}

어떠신가요 바로 이해가 되셨나요?

제가 시리얼라이저를 변환기, 모양 틀로 설명드린게 이런 맥락이었습니다.

 

각 view에서 무언가 데이터를 요청할 때,

지금 예시에서는 PersonAPI는 사람에 대한 데이터, EmailAPI에서는 이메일에 대한 데이터를 요청할 때 각각 원하는 형태로 응답해줘야 합니다. 하지만 모델은 하나니 필요한 데이터만 골라서 보내줘야겠죠?

이 역할을 해주는게 시리얼라이저라고 이해하시면 됩니다.

 

내가 보낼 데이터(now_person(즉, 모델 인스턴스))를 시리얼라이저에 넣어 변환시키고

그 데이터를 응답으로 보내주는 것이 시리얼라이저 - 뷰 연동 개념입니다.


4. ModelSerializer

앞서 진행한 코드에서 한가지 설명 안하고 그냥 넘어간 코드가 있습니다.

바로 시리얼라이저를 선언할 때 사용한 serializers.ModelSerializer입니다.

# test/serializers.py
# ModelSerializer 뒤에서 설명합니다.
class BasePersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('id', 'name', 'phone', 'addr')

원래 가장 기본적인 형태의 시리얼라이저 선언 방법은 serializers.Serializer를 상속 받는 것입니다.

이 형태로 선언하면 다음과 같이 코드를 작성할 수 있습니다.

# test/serializers.py
class BasePersonSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()
    phone = serializers.CharField()
    addr = serializers.CharField()

    def create(self, validated_data):
        """
        검증한 데이터로 새 `Person` 인스턴스를 생성하여 리턴합니다.
        """
        return Snippet.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        검증한 데이터로 기존 `Person` 인스턴스를 업데이트한 후 리턴합니다.
        """
        ...
        ...
        return instance

위에서 작성한 시리얼라이저보다 훨씬 길고 복잡해졌죠?

원래 시리얼라이저를 선언할 때는

1. 데이터 형태에 대한 필드(앞선 방법에서는 fields, 지금은 일일이 선언),

2. 그리고 그 데이터를 어떻게 처리할건지에 대한 메소드가 필요합니다.

 

이 메소드는 create나 update와 같이 이미 선언되어있는 메소드를 재작성하는 것이며,

views.py에서 직접 create나 update를 해야 할 것을 시리얼라이저에서 대신 해주는 것이라고 보면 됩니다.

대략 그런 역할을 선언해주고 필드에 대한 상세적인 내용을 직접 정의해야 했다면

 

serializers.ModelSerializer는 이 내용들을 알아서 해준 형태의 시리얼라이저라고 보시면 됩니다.

따라서 웬만하면 저희는 간편한 ModelSerializer의 형태로 선언하겠습니다. ★★


5. 마치며

여태까지 Django Rest Framework에서 가장 중요한 개념인 시리얼라이저에 대해 배웠습니다.

코드 작성 없이 보면서 따라가느라 조금 지루하셨을텐데,

다음 포스트에서는 이렇게 열심히 공부한 개념을 실제 게시판 프로젝트에 적용하겠습니다.

가장 첫 단계인 회원 인증부터 시작합니다:)


출처

https://devkor.tistory.com/entry/03-Django-Rest-Framework-Serializer-View-%EA%B0%9C%EB%85%90-%EC%9D%B5%ED%9E%88%EA%B8%B0?category=734691 

 

02. Django Rest Framework, Serializer, View 개념 익히기

Hello World 코드 설명 # (수정) 추후 설명하는 그림을 첨부할 예정입니다. GET 127.0.0.1:8000/api/hello/ 지난 시간에 해당 주소로 요청을 보내면 hello world를 print하는 api를 만들었습니다. 각 단계를 다시..

devkor.tistory.com

 

+ Recent posts