노트

DRF 시리얼라이저

Django REST Framework Serializers

백엔드#django · 연결된 개념 6개

쉽게 말하면

DRF 시리얼라이저는 모델 객체를 내보낼 땐 정해진 신고서 양식에 옮겨 적고, 들어오는 데이터는 세관처럼 검사한 뒤 모델로 들여보내는 틀이에요. 나가는 모양과 들어오는 규칙을 한곳에 선언하죠.

비유가 깨지는 곳 신고서를 실제 JSON 바이트로 바꾸는 건 시리얼라이저가 아니라 파서·렌더러 몫이에요. 들어온 데이터는 is_valid()를 먼저 불러야 검증되고, 실패하면 serializer.errors에 필드별로 담겨요.

DRF(Django REST Framework)의 시리얼라이저는 모델 인스턴스·QuerySet을 JSON으로 바꿀 수 있는 파이썬 기본 자료형으로 바꾸고(직렬화, serialization), 반대로 들어온 데이터를 검증해 모델로 만드는(역직렬화, deserialization) 틀이다. 장고의 Form과 비슷하게 필드와 검증 규칙을 선언한다.

직렬화:   QuerySet → (serializer.data) dict → (Renderer) JSON 응답
역직렬화: JSON 요청 → (Parser) dict → (is_valid) 검증 → (save) 모델
  • 응답으로 내보낼 때는 to_representation, 받아들일 때는 to_internal_value가 호출된다. 출력 모양을 바꾸려면 to_representation을 덮어쓴다
  • JSON 변환 앞뒤는 파서(parser)·렌더러(renderer)가 맡는다(DRF 파서·렌더러와 콘텐츠 협상)

Serializer와 ModelSerializer

class MovieSerializer(serializers.ModelSerializer):
    review_count = serializers.SerializerMethodField()
 
    class Meta:
        model = Movie
        fields = ["id", "title", "description", "active", "review_count"]
        read_only_fields = ["id"]
 
    def get_review_count(self, obj):
        return obj.reviews.count()
 
    def validate_title(self, value):                 # 필드 단위
        if len(value) < 2:
            raise serializers.ValidationError("제목은 두 글자 이상")
        return value
 
    def validate(self, data):                         # 여러 필드에 걸친 검증
        if data["title"] == data.get("description"):
            raise serializers.ValidationError("제목과 설명이 같을 수 없습니다")
        return data
  • ModelSerializer는 모델에서 필드와 기본 검증기를 자동으로 만들고 create()·update()를 기본 구현한다. 일반 Serializer는 모두 직접 쓴다
  • 검증은 세 층이다: validate_<필드>, validate(), 필드의 validators=[...]
  • 역직렬화할 때는 반드시 serializer.is_valid()를 먼저 부르고, 실패하면 serializer.errors에 필드별 오류가 담긴다. is_valid(raise_exception=True)면 400 응답으로 바로 이어진다
  • read_only, write_only(비밀번호), required, source(다른 속성 이름에서 읽기) 같은 핵심 인자로 입출력을 나눈다

관계 표현

  • 중첩 시리얼라이저(nested serializer): 연관 객체 전체를 넣는다
  • StringRelatedField: 연관 객체의 __str__ 결과
  • PrimaryKeyRelatedField: 연관 객체의 pk만
  • HyperlinkedRelatedField·HyperlinkedModelSerializer: pk 대신 상세 API URL. 시리얼라이저에 context={"request": request}를 넘겨야 한다

중첩 관계를 직렬화할 때 쿼리가 폭증하지 않게 뷰의 QuerySet에서 select_related·prefetch_related를 건다(Django 모델 매니저와 QuerySet, N+1 문제). 스프링에서는 DTO(Data Transfer Object)와 Bean Validation이 같은 역할을 나눠 맡는다.

출처: DRF Serializers: Validation · ModelSerializer · Overriding serialization and deserialization behavior · DRF Serializer relations

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • DRF 필터·검색·정렬

    DRF의 목록 API는 쿼리 파라미터로 결과를 좁히는 세 가지 장치를 붙일 수 있다. 값이 정확히 맞는 것만 고르는 필터, 일부 문자열로 찾는 검색, 순서를 바꾸는 정렬이다. 모두 제네릭 뷰(GenericAPIView 계열)의 filter_backends로 적용된다.

  • DRF 뷰 계층

    DRF는 같은 API를 점점 더 적은 코드로 쓰게 해 주는 뷰 계층을 제공한다. 함수 뷰 → APIView → 제네릭 뷰(generic view)와 믹스인(mixin) → 구체 제네릭 뷰 → ViewSet과 Router 순으로 올라갈수록 관례가 많아지고 코드가 줄어든다.

  • DRF 인증과 권한

    DRF는 요청 처리를 두 단계로 나눈다. 인증 클래스(authentication class)는 요청을 보낸 사용자가 누구인지 식별해 request.user·request.auth를 채우기만 하고, 권한 클래스(permission class)가 그 사용자에게 이 요청을 허용할지 결정한다. 인증만으로는 요청이 막히지 않는다(authn-authz).

  • 스프링 REST 컨트롤러

    @RestController는 메서드의 반환값을 뷰 이름이 아니라 HTTP 응답 본문(보통 JSON)으로 쓰는 컨트롤러다. @Controller에 @ResponseBody를 합친 것으로, 직렬화(serialization)는 Jackson이 맡는다.

  • Spring MVC 요청 흐름

    Spring MVC는 모든 HTTP 요청을 DispatcherServlet 하나가 받아, 알맞은 컨트롤러 메서드로 보내고 결과를 응답으로 바꾸는 프런트 컨트롤러(Front Controller) 구조다. 스프링 이전에는 URL마다 서블릿을 직접 만들고 매핑했다.

보기 옵션