[Django] Serializer, Serializer, SERIALIZER - 1

SangHun·2021년 6월 21일
0
post-thumbnail
post-custom-banner

필자가 Serializer를 처음 마주하게 된 것은
현재 회사의 백엔드 Django 코드를 봤을 때였다.
내 사수 개발자도 이게 정확히 뭔지 알려주진 않았었고,
그저 공식 문서를 읽어라라고 할 뿐.

난잡한 코드와 공식 문서를 번갈아가며 읽어봐도 도통 감이 오질 않았다.
지금도 감이 덜 왔다.
가장 좋은 방법은,
직접 코드를 작성해보며 Serializer가 없을 때와 있을 때의 차이를 비교하는 것이 아닐까 싶다.


가정

프레임워크: Django
요구사항: 가수의 데이터를 받아서 처리하는 API 서버

먼저, 가수 class를 만들고 여기에 맞게 데이터를 입력받게 하자.

class Artist:
    def __init__(
        self,
        name: str,
        number: int,
        genre: str,
        company=None,
        members=None,
        debut_dt=None,
        dismiss_dt=None,
    ) -> None:
        self.name = name
        self.number = number
        self.company = company
        self.members = members
        self.genre = genre
        self.debut_dt = debut_dt
        self.dismiss_dt = dismiss_dt

뭔가 데이터가 많이 필요하다...
어쨋든!

이제 view 파일을 만들자.

# views.py

def create_artist(request, *args, **kwargs):
    data = json.loads(request.body)
    artist = Artist(**data)
    
    return_data = do_something(artist)
    
    return HttpResponse(return_data)

음, 매우 간단하다.
그런데 나는 입력받는 데이터를 strict하게 검증하고 싶다.
namegenre, company의 길이가 10이 넘어가지 않을 때,
그리고 number가 숫자일 때만 받고 싶다!!

Without serializer

# views.py

def create_artist(request, *args, **kwargs):
    data = json.loads(request.body)

    is_valid = True
    is_valid = (
        is_valid
        and len(data["name"]) < 20
        and isinstance(data["number"], int)
        and len(data["genre"]) < 20
        and len(data["company"]) < 20
    )
    if not is_valid:
        return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
    
    artist = Artist(**data)
    return HttpResponse(artist.name)

그어어억...
검증하고 싶은 데이터가 많아질수록 코드가 길어진다.
물론 코딩 천재라면 검증 템플릿 코드를 슥-삭 만들어내겠지만,
이럴 때 쓰라고 만든게 serializer 이다.
있는거 잘 갖다 쓰자!

With serializer

class ArtistSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=20)
    number = serializers.IntegerField()
    genre = serializers.CharField(max_length=20)
    company = serializers.CharField(max_length=20)

def create_artist(request, *args, **kwargs):
    data = json.loads(request.body)

    serializer = ArtistSerializer(data=data)
    is_valid = serializer.is_valid()
    if not is_valid:
        return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
    
    artist = Artist(**serializer.validated_data)
    return HttpResponse(artist.name)

Piece of information

Serializers.is_valid()
Serializers.validated_data
Serializers.errors

위 어트리뷰트는 매우 유용하다.
간단히 설명드리자면
.is_valid() 메소드로 serializer가 입력받은 데이터를 검증하고,
검증 결과를 bool 값으로 반환한다.

.is_valid() == True 인 경우,
.validated_data 어트리뷰트가 생성된다.
Serializers.dataSerializers.validated_data의 차이는,
전자는 serializer가 입력받은 데이터를 그대로 반환해준다.
후자는 serializer에서 정의된 대로 검증된 데이터만 반환해준다.

.is_valid() == False 인 경우,
.errors 어트리뷰트가 생성된다.
데이터의 잘못된 부분을 알려준다.
출력 찍어보면 대략 아래처럼 나온다.

{'number': [ErrorDetail(string='A valid integer is required.', code='invalid')]}

So what?

사실 지금까지 보면,
그래서 뭐? 싶을 수 있다.
그냥 검증 코드를 내가 직접 작성하는 편이 더 나아보이기도 하고,
고작 저거 하려고 난해한 라이브러리를 가져다 써야하나 싶기도 하고.

하지만 serializer의 진짜 힘은
DB 모델과 결합할 때 나온다.
DB 모델과 함께쓰는 ModelSerializer에 대해서는...

다음에 알아보도록 하자...
끄억

profile
개발괴발자
post-custom-banner

0개의 댓글