[Django] - Serializers, JsonResponse

KimJiHong·2023년 10월 16일
1

Django and API

목록 보기
5/9
post-thumbnail

Serialize, Deserialize?

웹 프레임워크에서 Serialize(직렬화) 는 model 객체를 다른 형식으로 "변환" 하는 것을 의미하며,
Deserialize(역직렬화) 는 다른 형식으로 변환된 객체를 복원하는 과정을 의미한다.

즉, model 객체를 다른 형식 (ex. JSON) 으로 변환하여 파일이나 네트워크를 통해 다른 클라이언트에게 전송하기 위해 직렬화를 사용한다.

아두이노에서 예를 들면, 아두이노는 웹 브라우저를 직접 실행하지 못해 서버에서는 아두이노에서 온 HTTP 요청을 JSON 형식으로 직렬화(Serialize)하여 전송하고,
아두이노에서는 서버로부터 받은 JSON 데이터를 역직렬화(Deserialize) 하여 데이터를 주고 받을 수 있다.

아래의 사진은 직렬화와 역직렬화를 통해 아두이노와 통신하는 예시 사진이다.



Django Serializer method

장고에서는 데이터 형식을 직렬화 하는 방법으로 2가지가 있다.

Serialize Method

  • serializers & JsonResponse (Django 내장 직렬화 모듈) :
    데이터베이스 관리와 데이터 파일 입출력 작업에 사용

  • djangorestframework 라이브러리 :
    다양한 클라이언트와 상호작용하기 위해 사용

장고 내장 직렬모듈인 serializers 와 직렬화된 데이터를 클라이언트로 보내는 JsonResonse 를 사용하거나,
DRF (Django REST Framework) 라이브러리를 사용해서 REST API 서버로 구성하여 다양한 클라이언트 (ex. 모바일 앱) 들과 통신하는 방법이 있다.

후자의 장고 확장 라이브러리인 DRF를 사용하는 것은 데이터 직렬화, 역직렬화 뿐만 아니라 라우팅과 인증 등 다양한 API 관련 기능을 사용할 수 있다.

이번 게시글에서는 DRF에 대해서 다루지 않고, 장고 내장 모듈 serializers 와 JsonResponse 를 사용하여 JSON 데이터를 클라이언트로 보내는 것을 알아보자.



Serializers & JsonResponse

내장 직렬화 모듈을 사용하는 간단한 예제를 작성해보자.

내장 직렬화를 위해 사용하는 모듈은 serializers, JsonResponsejson 이며, 모델 데이터를 JSON으로 직렬화하여 클라이언트에게 전송한다.

# myapp/views.py

from django.core import serializers
from django.http import JsonResponse
from .models import testDB
import json

app_name = 'myapp'

def serialize_testDB(request):
    get_object = testDB.objects.all()

    # testDB 모델 객체를 JSON 형식의 "문자열"으로 직렬화
    # 가져올 필드들은 fields 변수 내에 지정
    testDB_list = serializers.serialize('json', get_object, fields=('char_fields1', 'char_fields2'))

    # JSON 형식의 "문자열"을 JSON 형식으로 변경
    testDB_JSON = json.loads(testDB_list)

    # 직렬화한 데이터를 클라이언트로 전송
    # safe 변수를 False 로 하여 dict 이외의 형식도 반환 가능
    return JsonResponse({"test":testDB_JSON}, safe=False)

serializers

serializers 를 이용하여 JSON 형식으로 직렬화 한다고 해서 바로 JSON 형식으로 바뀌는게 아니다.
serializers 는 단지 JSON 형식의 "문자열" 로 바꿔주는 역할이라는 것을 주의해야한다.

only use serializers

한번 직렬화만 진행하고 JsonResponse 가 어떻게 나오는지 확인해보자.

# 직렬화만 진행한 testDB_list 를 반환해보자.
return JsonResponse(testDB_list, safe=False)

위와 같이 JSON 형식을 가지는 문자열 "" 로 표현된다.

DICT response

그럼, 어떻게 해야지 dict(딕셔너리) 형태의 JSON 데이터를 response 할 수 있을까?

이는 처음 코드처럼 문자열로 직렬화 된 testDB_list 를 json 라이브러리를 통해서 JSON 형식으로 변환해 주고

JsonResponse 시 딕셔너리의 value 값으로 설정하면 딕셔너리 형태로 response 된다.

testDB_JSON = json.loads(testDB_list)

# 이 경우에는 safe=True 도 가능
# safe 변수에 대해서는 바로 아래에서 설명
return JsonResponse({"test":testDB_JSON}, safe=False)

저장되는 value 들을 보면
장고 모델, pk, 내가 지정한 fields들 3가지가 저장된다.


JsonResponse 의 매개변수 safe

매개변수 safe 는 JSON 응답 type이 딕셔너리(dict) 인지 아니면 그 외의 형식인지 확인하는 변수이다.

기본값은 safe = True 로 딕셔너리 형식만 받아들이고, False 값으로 설정시에 딕셔너리 이외의 형식도 받아들일 수 있다.

만약 True 로 설정해두고, 딕셔너리 이외의 값을 보낸다면 Type error 를 마주하게 될 것이다.

올바른 사용

>>> response = JsonResponse({"key1":"value1", "key2":"value2"}, safe=True)
>>> response = JsonResponse({"key1":[1, 2, 3], "key2":"value1"}, safe=True)
>>> response = JsonResponse([1, 2, 3], safe=False)

잘못된 사용

>>> response = JsonResponse([1, 2, 3], safe=True)
>>> response = JsonResponse({[1, 2, 3]}, safe=True)

TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.

safe 매개변수는 JSON 응답의 형식을 제어하기 위해서 매우 중요한 변수중 하나이므로 사용시 주의하자!


Deserialize

클라이언트로 부터 JSON 형식의 데이터를 받았을 때
바로 데이터베이스에 데이터를 저장할 수 없어 deserialize(역직렬화) 과정을 통해 데이터 형식을 복구 해야한다.

예를들어 서버에서 receive 된 json_data 가 아래와 같다고 해보자.

json_data = '[{"model": "myapp.testdb", "pk": 3, "fields": {"char_fields1": "hellow", "char_fields2": "hellow"}}]'

이제 이 JSON 형식을 역직렬화 하여 데이터 베이스에 저장해보자.

# JSON 데이터를 Python 객체로 역직렬화
deserialized_data = serializers.deserialize('json', json_data)

for obj in deserialized_data:
    obj.save()

json_data 에서 모델이 "model": "myapp.testdb" 로 지정되어 myapp의 testDB 내에 해당 JSON 데이터가 역직렬화 되어 저장된다.


많은 큰 규모의 기업들은 모바일 기기와 같이 HTTP 프토토콜을 기반으로 한 다양한 클라이언트들과 플랫폼들이 등장하였고
서버를 구현할 때 REST API과 같이 여러 플랫폼과 통신을 원활하게 해줄 방법이 필요해졌다.

다음 게시글에서는 DRF (Django REST Framework) 에 대해서 알아보도록 하겠다.



틀린 부분이 있다면 지적 정말 감사합니다. 바로바로 수정하겠습니다.
profile
대충 할거면 시작도 하지 말자

0개의 댓글