DevOps/Django

[DRF] 직렬화, 역직렬화

bestwish 2022. 3. 23. 00:08

 

직렬화와 역직렬화

DRF에서는 직렬화, 역직렬화가 따로 있는 것이 아니라, Serializer가 두 기능을 제공한다.

 

 

Serializer

  • Serializer는 Form과 Model 둘 다 비슷해 보이기도 하다.
    • Form
      • HTML을 다루기 위한 것.
    • Model
      • DB Table을 다루기 위한 것.
  • 이 두개 모두 유효성(validation)과 직렬화(serialization) 기능을 모두 제공한다.
  • 유효성과 직렬화를 포함하는 클래스가 Serializer 클래스 이다.

 

 

Serialization

1. 메모리 내부 ( 파일, DB, Network) ↔ 외부

  • 메모리 환경이 다르기 때문에 값 그대로 저장 할 수 없다.
    • “홍길동” string을 내부에서 메모리 외부로 보내려면 bytes로 변환 후 보내야한다.
    • 99 integer를 메모리 내부에서 외부로 보냈다가 다시 내부로 보내면 integerstring으로 변환된다.
    • 💡이런 상황의 문제가 분명하게 드러날 때는 Class를 사용할 때다.
  • Class 데이터를 메모리 내부로 저장할 때, serializer를 사용하여 저장한다.
  • 복원을 할 때는 deserializer를 이용한다.
  • JSON포맷을 하는 것이 serializer를 하는 방법 중에는 가장 간단한 방법이다.

2.직렬화 / 역직렬화

  • 순서
serialize 직렬화 deserialize 역직렬화
DB에서 instance를 가져온다. Client에게 json data를 받는다.
Serializer(instance=XXX) 받은 json data를 dict타입으로 바꾼다.
Serializer를 통해 dict 타입으로 만든다. Serializer(data=XXX)
json data로 만든다. is_valid()을 통해 유효값인지 확인한다.
response한다. validated_data를 만든다.
  instance를 만든다.
  save()를 통해 DB에 저장한다.
GET POST, UPDATE, DELETE, PATCH

 

 

 


 

 

직렬화 코드 순서

  • 클라이언트에게 데이터를 보낼 때 사용한다.
  1. data를 db에서 가져온다.
  2. serialize 직렬화하여 json data로 만든다.
  3. response
# django shell

# 1
>>> from api2.serializers import *
>>> CommentSerializer()
CommentSerializer():
    id = IntegerField(label='ID', read_only=True)
    content = CharField(label='CONTENT', style={'base_template': 'textarea.html'})
    create_dt = DateTimeField(label='CREATE DT', read_only=True)
    update_dt = DateTimeField(label='UPDATE DT', read_only=True)
    post = PrimaryKeyRelatedField(allow_null=True, queryset=Post.objects.all(), required=False)

# 2
>>> c0 = Comment.objects.all()[0]
>>> sr = CommentSerializer(instance=c0) # 직렬화 한다.
>>> sr.data
{'id': 1, 'content': '첫번째 댓글 입니다.', 'create_dt': '2021-07-28T07:06:54.974180', 'update_dt': '2021-07-28T07:06:54.974180', 'post': 3}
>>> data0 = sr.data
>>> type(data0)
<class 'rest_framework.utils.serializer_helpers.ReturnDict'> # 딕셔너리인데 DRF에서 기능을 추가한 DRF 이다.

# 3
>>> from rest_framework.renderers import JSONRenderer 
>>> JSONRenderer().render(data0)
b'{"id":1,"content":"\xec\xb2\xab\xeb\xb2\x88\xec\xa7\xb8 \xeb\x8c\x93\xea\xb8\x80 \xec\x9e\x85\xeb\x8b\x88\xeb\x8b\xa4.","create_dt":"2021-07-28T07:06:54.974180","update_dt":"2021-07-28T07:06:54.974180","post":3}'
>>> json0 = JSONRenderer().render(data0)
>>> type(json0)
<class 'bytes'>

 

 


 

 

역직렬화 코드 순서

  • 클라이언트에게 데이터를 받아 DB에 저장할 때 사용한다.
  1. json 타입을 받는다.
  2. dict 타입으로 만든다.
  3. 최종적으로 인스턴스로 만들어서 DB에 저장한다.
# django shell

# 1, 2
>>> from rest_framework.parsers import JSONParser
>>> from io import BytesIO
>>> JSONParser().parse(BytesIO(json0))
{'id': 1, 'content': '첫번째 댓글 입니다.', 'create_dt': '2021-07-28T07:06:54.974180', 'update_dt': '2021-07-28T07:06:54.974180', 'post': 3}
>>> ddata0 = JSONParser().parse(BytesIO(json0))
>>> type(ddata0)
<class 'dict'>

# 3
>>> ddata0 = JSONParser().parse(BytesIO(json0))   
>>> deserializer = CommentSerializer(data=ddata0)
>>> deserializer.is_valid() # 유효성 검사를 꼭 해주어야 한다.
True
>>> deserializer.errors # 에러가 나면 이 메서드를 통해 확인 가능하다.
{}
>>> deserializer.validated_data  
OrderedDict([('content', '첫번째 댓글 입니다.'), ('post', <Post: 유럽 여행 중 파리 개선문 다녀 왔답니다.>)])
>>> instance = Comment(**deserializer.validated_data)
>>> instance.save()