django

DRF Serializer

Jueuunn7 2024. 9. 18. 03:49

내가 생각하는 DRF의 가장 큰 장점은 Serializer이라고 생각한다.

Serializer는 json, python, xml 객체간의 직렬화를 쉽게 해주며 데이터를 검증하며 이걸 다시 다른 형태로 역직렬화 시킬 수 있다.

 

1. Serializer 선언

간단한 Board 클래스 하나를 선언해준다.

>>> class Board:
...     def __init__(self, title, content):
...             self.title = title
...             self.content = content
...
>>> board = Board("Hello", "World!")

 

시리얼라이저저를 사용하는 방법은 모델을 선언하는 방법과 비슷하다.

>>> class BoardSerializer(serializers.Serializer):
...     title = serializers.CharField()
...     content = serializers.CharField()
...

 

1.1 직렬화, 역직렬화

시리얼라이저로 직렬화, 역직렬화 하는 방법은 매우 간단하다.

>>> serializer = BoardSerializer(board)
>>> serializer.data
{'title': 'Hello', 'content': 'World!'}

>>> serializer = BoardSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.validated_data
{'title': 'Hello', 'content': 'World!'}

역직렬화 하기 전엔 .is_valid()를 호출해서 json 데이터가 시리얼라이저 형식에 맞는지 먼저 검사를 해줘야한다.

 

1.2 create, update

시리얼라이저로 인스턴스를 저장, 업데이트하려면 .update, .create 메서드를 구현해야한다.

    def create(self, validated_data):
        return Board.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.title = validated_data.get('title', instance.title)
        instance.content = validated_data.get('content', instance.content)
        instance.save()
        return instance

장고 모델인 경우엔 이런식으로 메서드를 구현할 수 있다.

serializer = BoardSerializer(data=data)
serializer = BoardSerializer(board, data=data)

serializer가 초기화될때 인스턴스가 존재하는지 여부에 따라서 create나 update가 호출될지 결정된다.

serializer = BoardSerializer(pk=pk)

해당 방식으로 create, update 메서드가 호출될때 validated_data에 추가 인수를 넣어서 호출할 수 있다.

 

1.3 is_valid()

시리얼라이저의 데이터를 역직렬화 시킬때에는 반드시 is_valid 메서드를 호출해야한다. 

is_valid는 bool을 반환하며 만약 에러가 있을 경우에 .errors에 에러 메세지를 저장한다.

is_valid 파라미터에 raise_exception=True를 주면 에러 발생시 바로 응답 400 bad request를 반환한다.

>>> serializer = BoardSerializer(data={'title': 'Hi'})
>>> serializer.is_valid()
False
>>> serializer.errors
{'content': ['This field is required.']}

 

추가로 검사하고 싶은 필드가 있으면 validate_<filedname>으로 메서드를 작성하면 된다.

    def validate_title(self, value):
        if 'Django' not in value.lower():
            raise serializers.ValidationError("Blog post is not about Django")
        return value

인스턴스 단위에서 검사하려면 validate를 작성하면 된다.

    def validate(self, data):
        if data['start'] > data['finish']:
            raise serializers.ValidationError("finish must occur after start")
        return data

 

1.4 partial=True, many=True

- partial=True

인스턴스의 값을 부분적으로 변경할때(patch) 해당 파라미터를 전달해야한다.

- many=True

인스턴스나 데이터가 배열의 형태이면 해당 파라미터를 전달해야한다.

'django' 카테고리의 다른 글

Django - Trailing Slash  (1) 2024.12.02
Django - DB Connection  (0) 2024.10.27
Django core - WSGI  (1) 2024.10.21
Django ORM - Transaction  (0) 2024.08.06
Django - Nginx + Gunicorn으로 배포하기  (1) 2024.06.21