직렬화 ( Serialization )
모든 프로그래밍 언어의 통신에서 데이터는 필히 문자열(혹은 byte data)로 표현되어야만 한다.
송신자 : 객체를 문자열로 변환하여, 데이터 전송 -> 직렬화
수신자 : 수신한 문자열을 다시 객체로 변환하여, 활용 -> 비직렬화
각 언어에서 모두 지원하는 직렬화 포맷 (JSON, XML 등) 도 있고, 특정 언어에서만 지원하는 직렬화 포맷 (파이썬은 Pickle) 이 있다.
데이터를 같아도, 응답형식이 다를 수 있습니다.
보통의 웹 세상에서는 ...
- GET 요청에 대해 HTML 포맷으로 응답
- POST 요청을 application/x-www-form-urlencoded 인코딩 혹은 multipart/form-data 인코딩으로 요청하고, HTML 포맷으로 응답
요즘의 API 서버에서는 대게 JSON 인코딩된 요청/응답
JSON 포맷과 PICKLE 포맷 (1/2)
JSON 포맷
- 다른 언어/플랫폼과 통신할 때 주로 사용.
- 표준 라이브러리 json 제공 (파이썬 기본 데이터 타입에 대해서는 변환 Rule을 제공하지만,
django model이나 QuerySet이나 우리가 직접 만든 우리가 직접 만든 type에 대해서는 직렬화 Rule이 없다는 의미.
개발자가 Rule을 추가할 수는 있다.)
- pickle에 비해 직렬화를 지원하는 데이터타입의 수가 적지만, 커스텀 Rule 지정도 가능
PICKLE 포맷
- 파이썬 전용 포맷으로서 파이썬 시스템끼리만 통신할 때 사용 가능
- 표준 라이브러리 pickle 제공 -> json 라이브러리가 유사한 사용 방법
- 주의) 파이썬 버전 특성을 타는 경우가 있다.
json과 pickle 형식으로 직렬화 했을 때 서로 다르게 직렬화 되는 것을 확인할 수 있다.
python manage.py shell 에서 User Object QuerySet을 하나 가져와서 직렬화 하려 하면 바로 위의 serializable 에러가 난다.
QuerySet Type의 객체에 대해서는 JSON serializable 할 수 없다. 다시말해서 QuerySet Type 객체를 직렬화하는 Rule을 모르겠다는 의미.
모델 객체 하나를 넘길 때는 modelSerializer의 many=False (default) 로 사용하여야 하는데,
QuerySet을 넘길 때는 위 사진처럼 many=True로 지정해 주어야 한다.
위처럼 serializer.data 는 파이썬 기본 Object이기 때문에 json.dumps()으로 직렬화 되는 것을 확인할 수 있다.
※ View에서의 JSON 응답
장고 기본 View에서의 HttpResponse JSON 응답
모든 View는 HttpResponse 타입의 응답을 해야만 한다.
일반적으로 다음 2가지 방법
1. 직접 json.dumps를 통해 직렬화된 문자열을 획득하여 HttpResponse를 통해 응답
2. 1번을 정리하여 JsonResponse 지원 (JsonResponse 는 json.dumps기능과 HttpResponse기능을 사용, 상속받아서 구현한 클래스 )
-> 내부적으로 json.dumps를 사용하며 DjangoJSONEncoder가 디폴트 지정
(이 사실을 안다면, DjangoJSONEncoder 어떤 타입에 대해서 변활 Rule이 제공되고, 제공 안되는지 이해할 수 있다.)
※ DRF를 통한 JSON 응답
※ 실제 DRF Serializer 활용
list 기능 하나만 사용하려면 generics.ListAPIView
이전에 정의했던 기능 5개 기능 다 사용하려면 ModelViewSet 사용해야함,
호출 URL은 아래와 같이 정의
path('public/', views.PublicPostListAPIView.as_view()),
# GET 으로만 동작하는 클래스 상속
class PublicPostListAPIView(generics.ListAPIView):
# GET, POST 모두 동작하는 클래스 상속
class PublicPostListAPIView(generics.ListCreateAPIView):
아래 소스는 위 방법 1, 2 모두 각각 사용하여 구현해본 코드이다.
from django.contrib.auth import get_user_model
from rest_framework import serializers
from .models import Post
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ['username','email']
class PostSerializer(serializers.ModelSerializer):
#username = serializers.ReadOnlyField(source='author.username')
author = AuthorSerializer()
class Meta:
model = Post
fields = [
'pk',
#'username',
'author',
'message',
'created_at',
'updated_at'
]
'장고 프레임워크' 카테고리의 다른 글
views.py에 관하여 (0) | 2020.06.04 |
---|---|
Django Template 문법에 관하여 (0) | 2020.06.03 |
Django Model 관계에 관하여. (0) | 2020.06.03 |
1. API Server와 Rest (0) | 2020.05.29 |
장고 DB ORM 사용법 (0) | 2020.02.28 |
댓글