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에서 가장 중요한 개념인 시리얼라이저에 대해 배웠습니다.
코드 작성 없이 보면서 따라가느라 조금 지루하셨을텐데,
다음 포스트에서는 이렇게 열심히 공부한 개념을 실제 게시판 프로젝트에 적용하겠습니다.
가장 첫 단계인 회원 인증부터 시작합니다:)
출처
'Django > DRF' 카테고리의 다른 글
[DRF] Image 를 create, update 하려면.. (0) | 2022.02.03 |
---|---|
[DRF] 03. Django Rest Framework 회원 인증, 유저 모델 확장하기 (0) | 2022.01.25 |
[DRF] 01. Django Rest Framework 개발 환경 세팅 (0) | 2022.01.24 |
[DRF] 00. 들어가며 - Django Rest Framework로 게시판 만들기 (0) | 2022.01.24 |