본문 바로가기

Django

django serializer (serializers.Serializer)

serializer란?

serializer는 데이터를 직렬화 할 수 있게 도와준다.

예를 들어 사용자 DB에 이메일, 이름, 전화번호 등등의 데이터가 있다고 하면

해당 내용들을 JSON or Dict로 직렬화 할 수 있다.

그리고 serializer는 두가지로 나뉘어 지는데 Serializer / Deserializer로 나뉘어 사용 가능하다.

각각의 의미에 대해서 먼저 알아보자

Serializer

python 객체나 django에서 queryset등 복잡한 객체들을 REST API에서 사용 가능하게 json 형태로 변환해준다.

Deserializer

데이터를 request body로 부터 받아서 다시 복잡한 데이터로 변환 해주는 작업(serializer 처리를 하기 이전 상태로)

(참고 - Deserializer를 사용할때는 is_valid()를 호출 하여 검사해야한다.)

Serializer 구성 및 사용하기

from rest_framework import serializers

class UserSerializer(serializers.Serializer):
      email = serializers.EmailField()
    name = serializers.CharField(max_length=20)
    phone = serializers.CharField(max_length=20)
    age = serializers.IntegerField()
    created = serializers.DateTimeField()

serializer

def index(request):
      if request.method == 'GET':
          user = request.user
          serializer = UserSerializer(user).data
        return Response(serializer)

deserializer

def index(request):
      if request.method == 'POST':
          serializer = UserSerializer(data=request.data)
        if serializer.is_valid()  # bool으로 True/False가 리턴됨
                data = serializer.save()
              serializer = UserSerializer(data).data
              return Response(serializer)
# 참고
# serializer.is_valid() 이후 확인 해볼 수 있는 작업
# serializer.validated_data -> 역직렬화된 값들을 직접 확인해 볼 수 있다.
# serializer.errors -> is_valid()에서 실패했을때 이유를 알 수 있는 구문이다.

create() / update() 메소드 오버라이딩 해서 사용

from rest_framework import serializers

class UserSerializer(serializers.Serializer):
      email = serializers.EmailField()
    name = serializers.CharField(max_length=20)
    phone = serializers.CharField(max_length=20)
    age = serializers.IntegerField()
    created = serializers.DateTimeField()

    def create(self, validated_data):
          return User(**Validated_data)

    def update(self, instance, validated_data):
          instance.email = validated_data.get('email', instance.email)
        instance.name = validated_data.get('name', instance.name)
        instance.phone= validated_data.get('phone', instance.phone)
        instance.age= validated_data.get('phone', instance.age)
        instance.created= validated_data.get('phone', instance.created)
        instance.save()
        return instance

위의 create()와 update()는 따로 선언 해줄 필요가 없다.

왜냐하면 serializer.save()를 하면 자동적으로 create() 및 update()를 해주기때문이다.

두개를 어떻게 구분하는지는 instance의 존재 유무에 따라 다르다.

instance가 있으면 update 아니면 create 해준다.

코드로 보자면 serializer = UserSerializer(data=data) 가 create() 이고

serializer = UserSerializer(user, data=data) 가 update()이다.

validate() 메소드 오버라이딩

데이터를 생성 및 수정할때 검수하는 부분이다.

from rest_framework import serializers

class UserSerializer(serializers.Serializer):
      email = serializers.EmailField()
    name = serializers.CharField(max_length=20)
    phone = serializers.CharField(max_length=20)
    age = serializers.IntegerField()
    created = serializers.DateTimeField()

    def create(self, validated_data):
          return User(**Validated_data)

    def update(self, instance, validated_data):
          instance.email = validated_data.get('email', instance.email)
        instance.name = validated_data.get('name', instance.name)
        instance.phone= validated_data.get('phone', instance.phone)
        instance.age= validated_data.get('phone', instance.age)
        instance.created= validated_data.get('phone', instance.created)
        instance.save()
        return instance

        def validate(self, data):
        if self.instance:
            phone = data.get('phone', self.instance.phone)
        else:
            phone = data.get('phone')
        if len(phone) > 13:
            raise serializers.ValidationError('휴대폰 번호의 길이가 작습니다.')
        return data

validate도 instance가 있으면 update시 검수 하는 부분이고 없으면 create일때 검수 하는 부분이다.

위의 코드에선 한가지 데이터만 검수 했지만 여러가지 데이터를 넣고 다양한 조건을 넣어 사용 가능하다.

partial update

serializer를 수정(update)를 할때 전체가 아닌 일부만 수정 하고 싶을때 사용 할 수 있는 구문이다.

serializer = UserSerializer(user, data=request.data, partial=True)

뒤의 partial인자는 데이터를 모두 보내는 것이 아니라 내가 바꾸고 싶은 데이터만 보내겠다 라는 의미로 알면 된다.

만약 partial를 False나 인자로 담고 있지 않으면 모든 값을 업데이트 하기 바랄것이다.

중첩된 객체 다루기

중첩된 객체? 갑자기 무슨 중첩을 말하는 거냐면 위에서 사용했던 serializer들은 다 하나의 객체로만 사용한 serializer이다. 하지만 예를 들어 user의 list를 보겠다고 한다면 어떻게 해야할까?

serializer = UserSerializer(many=True) 를 인자로 사용하면 문제 없다.

그리고 추가적으로 한가지 더 serializer 인자로 context={}라는것도 있는데

예시를 하나 들어 보자면 context={'request': request} 로 선언되어 있다면 현재 선언된 serializer를 누가 보고 있는지 알수 있게 request를 serializer로 보내준것이다.

꼭 request가 아니어도 다른 인자로 context를 사용 가능하다.