본문 바로가기
프로그래밍/Django

🚀 Django REST Framework (DRF) - Serializer가 Response를 만들기까지 Serializer Core에 대하여

by 우주를놀라게하자 2025. 2. 27.
반응형
SMALL

🏗️ Django 기본 요청 흐름 (Request Flow)

Django에서 HTTP 요청이 처리되는 기본적인 흐름을 살펴보자.


HTTP 요청 → 서버 & 네트워크 장치 → WSGI (or ASGI) → HttpRequest → Django Middleware →[ 비즈니스 로직 ] → HttpResponse → Django Middleware → WSGI Handler → HTTP 응답

 

이 중에서 가장 중요한 부분은 비즈니스 로직을 처리하는 부분이다.

Django REST Framework(DRF)를 사용할 경우, 이 과정에 Serializer와 generics 기반 View가 추가된다! 🚀

📥 HTTP 요청  
    ⬇  
🌍 WSGI/ASGI 서버 (Gunicorn, Daphne 등)  
    ⬇  
📨 HttpRequest 생성 (Django)  
    ⬇  
🛑 Middleware 처리  
    ⬇  
🎯 [ 비즈니스 로직 실행 ]  
    ⬇  
📤 HttpResponse 반환  
    ⬇  
🚀 클라이언트에게 응답 전송

📌DRF를 사용하면?

비즈니스 로직을 처리하는 과정에서 Serializer & GenericAPIView를 활용하여 데이터를 JSON 응답으로 변환합니다!

🛠️ 2️⃣ DRF에서 요청이 처리되는 과정

 

1. 요청이 들어오면 APIView에서 시작된다!

  • DRF의 모든 View는 결국 APIView 클래스에서 출발한다. 즉, 우리가 자주 사용하는 generics 기반 View들도 내부적으로 APIView를 상속받고 있음!

2. GenericAPIView에서 데이터를 가져옴

  • GenericAPIViewAPIView를 확장하여 쿼리셋(queryset)과 직렬화(serializer)를 추가한 클래스입니다.즉, 데이터를 조회하고 JSON으로 변환하는 기능을 추가한 것!

3. Serializer를 사용해 데이터를 JSON으로 변환

Serializer는 쿼리셋(QuerySet) → Python 객체 → JSON 변환 역할을 합니다.

 

4. 최종적으로 Response 객체로 변환 후 반환


🔍 Django의 View 클래스 – DRF의 뿌리! 🌳

Django의 View 클래스는 모든 Django 및 Django REST Framework(DRF) 기반 View의 최상위 부모 클래스입니다. 즉, 우리가 APIViewGenericAPIView, generics를 사용하든, 그 뿌리를 따라 올라가면 결국 Django의 View 클래스로 연결됨! 🚀

View 클래스의 역할은?

Django에서 View 클래스는 HTTP 요청을 처리하는 기본적인 역할을 수행합니다.

즉,

  • 요청(request) 분배
  • HTTP 메서드(GET, POST, PUT 등) 매핑
  • 비즈니스 로직 처리 전후 기본 설정 제공

등을 담당하는 가장 기본적인 클래스입니다.

쉽게 말해, 모든 Django 뷰가 거쳐가는 출발점! 🏁

View 클래스의 주요 코드 분석

이제 View 클래스의 핵심 부분을 하나씩 살펴보겠습니다. 👀

 

1. http_method_names – 지원하는 HTTP 메서드 목록

http_method_names = ["get", "post", "put", "patch", "delete", "head", "options", "trace"]
  • Django가 지원하는 HTTP 메서드 목록
  • 해당 메서드가 정의되지 않은 경우 405 Method Not Allowed 응답을 반환

2. as_view() – Django에서 가장 중요한 뷰 엔트리 포인트!

@classonlymethod
def as_view(cls, **initkwargs):
  • 모든 Django View의 진입점(entry point)! 🏁
  • URL 패턴에 매핑될 때 호출되는 메서드
  • 뷰 클래스를 실제 함수형 뷰로 변환하여 반환

🎯 정리 – View 클래스의 핵심 역할

요청 처리 HTTP 요청을 적절한 메서드(GETPOST, etc.)로 분배
초기화 __init__()을 통해 동적 속성 저장
비동기 지원 view_is_async로 비동기 여부 판별
뷰 실행 as_view() → view() → dispatch() 순으로 실행
Django의 모든 View의 부모 클래스 APIViewGenericAPIView 등 모든 DRF 뷰가 상속받음

 

즉, Django의 View 클래스는 모든 뷰의 시작점이며,이 위에 APIView → GenericAPIView → generics가 확장되면서 DRF가 완성됨! 🚀


🔍 Django REST Framework의 APIView – DRF의 핵심 클래스!

 

Django의 View클래스를 기반으로 확장된 DRF의 핵심 클래스가 바로 APIView입니다.모든 DRF 기반 View의 출발점이 되는 클래스로, 이 클래스 위에 GenericAPIViewgenerics가 확장되면서 CRUD를 쉽게 처리할 수 있도록 지원합니다! 🚀


APIView는 뭘 하는 클래스인가?

Django 기본 View와의 차이점을 먼저 알아보자!

 APIView (DRF)   View (Django)
renderer_classesparser_classes 등 추가적인 API 설정 지원 HTTP 메서드 분배만 담당
인증(Authentication)권한(Permission)쓰로틀링(Throttling) 기본 제공 인증, 권한 처리가 없음
데이터 직렬화(Serialization) 및 역직렬화(Parsing) 지원 JSON 처리 직접 구현해야 함
as_view()에서 CSRF 예외 처리 적용 CSRF 처리 기본 적용됨

 

APIView에서 제공하는 주요 설정 값들

renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_METADATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

 

📌 이 설정들은 API의 동작을 결정하는 핵심 요소들!

 

  • renderer_classes → 응답 데이터를 어떤 포맷(JSON, XML 등)으로 변환할지 결정
  • parser_classes → 요청 데이터를 어떻게 해석할지 결정 (JSON, Form-data 등)
  • authentication_classes→ 인증 방식(JWT, Token, Session 등) 설정
  • permission_classes → 권한 체크 설정 (예: 로그인한 사용자만 가능)
  • throttle_classes → API 요청 제한 설정 (Rate Limiting)
  • content_negotiation_class → 요청의 Accept 헤더에 따라 데이터 형식 결정
  • metadata_class → API 문서화를 위한 메타데이터 클래스 설정
  • versioning_class → API 버전 관리 (v1, v2 같은 버전별 API 운영 가능)

GenericAPIView의 역할은?

🔥 APIView를 확장하여 쿼리셋(queryset)과 시리얼라이저(serializer)를 추가한 것!

즉, APIView가 요청과 응답을 다루는 기본 기능이라면, GenericAPIView는 데이터베이스와 연결된 CRUD 기능을 더 쉽게 사용할 수 있도록 도와줌! 🔥

 

1. queryset과 serializer_class 핵심 속성!

queryset = None
serializer_class = None

 

queryset → 이 View에서 사용할 데이터(QuerySet)를 지정하는 속성

serializer_class → 데이터를 변환(직렬화/역직렬화)할 Serializer 지정

📌 예제

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()  # User 모델의 모든 데이터를 가져옴
    serializer_class = UserSerializer  # User 데이터를 JSON으로 변환할 Serial

 

이제 UserListView는 User 모델의 데이터를 JSON으로 변환하여 반환함! 🚀

 

2. lookup_field – 객체 검색을 위한 필드

lookup_field = 'pk'
lookup_url_kwarg = None

 

lookup_field → 특정 객체를 찾을 때 사용할 기본 필드 (기본값: pk)

lookup_url_kwarg → URL에서 객체를 찾을 때 사용할 키워드 (None이면 lookup_field 사용)

📌 예제

class UserDetailView(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = "username"  # 기본적으로 `pk` 대신 `username`으로 검색!

 

이제 UserDetailView는 pk 대신 username을 기반으로 특정 유저를 검색 가능! 🔍

 

3. filter_backends – 쿼리셋 필터링 시스템

filter_backends = api_settings.DEFAULT_FILTER_BACKENDS

✅ filter_backends → 기본적으로 적용할 필터 시스템을 지정

📌 예제

from rest_framework import filters

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [filters.SearchFilter]  # 검색 기능 추가!
    search_fields = ['username', 'email']  # `username`과 `email`에서 검색 가능

 

이제 UserListView에서 ?search=값 을 URL에 추가하면 필터링이 가능! 🔥


GenericAPIView의 요청 처리 과정

이제 요청이 GenericAPIView에서 처리되는 과정을 살펴보자!

1. 요청이 as_view()를 통해 들어옴

view = GenericAPIView.as_view()
  • APIView에서 처리하는 as_view() 메서드를 그대로 상속
  • 내부적으로 dispatch() 호출

2. get_queryset()을 통해 데이터 가져오기

def get_queryset(self):
    return self.queryset.all()  # 캐싱 방지를 위해 `.all()` 사용!

 

쿼리셋을 가져오되 캐싱되지 않도록 .all()을 호출


 3. get_serializer()을 통해 시리얼라이저 가져오기

def get_serializer(self, *args, **kwargs):
    return self.serializer_class(*args, **kwargs)

 

지정된 serializer_class를 이용해 데이터를 JSON으로 변환!


 4. 적절한 HTTP 메서드(get(), post(), put() 등) 실행

  • get_queryset()을 실행하여 데이터를 가져오고
  • get_serializer()를 실행하여 JSON으로 변환
  • get()post() 등의 메서드에서 최종 응답 반환!

🎯 정리 – GenericAPIView의 핵심 역할

기능 역할

쿼리셋 처리 queryset 속성 또는 get_queryset()을 통해 데이터 가져오기
객체 검색 lookup_field, lookup_url_kwarg로 특정 객체 조회
데이터 필터링 filter_backends를 통해 자동 필터링 적용 가능
데이터 페이징 pagination_class를 설정하여 페이징 처리 가능
데이터 변환 get_serializer()를 통해 JSON 직렬화
CRUD 지원 generics를 상속받아 CreateAPIViewRetrieveAPIView 등으로 확장 가능

GenericAPIView는 APIView를 확장하여 DB와 연결된 데이터를 더 쉽게 다룰 수 있도록 한 클래스!

이제 ListAPIView, CreateAPIView 등은 GenericAPIView를 기반으로 CRUD 기능을 자동으로 제공!

 

이제 Django REST Framework(DRF)에서 Serializer가 데이터를 JSON Response로 변환하는 과정을 간략히 정리해볼게요!


1.  요청이 들어오면 APIView에서 처리 시작!

  • 클라이언트 → 서버로 HTTP 요청 전송
  • APIView.dispatch() 호출 → 적절한 HTTP 메서드(get()post()) 실행

2. GenericAPIView에서 데이터 가져오기

  • get_queryset() 실행 → 쿼리셋을 가져옴 (queryset.all())
  • **lookup_field**를 사용해 특정 객체 조회 (예: **id=1**인 유저 찾기)

3.  Serializer를 사용해 데이터 직렬화

  • get_serializer() 실행 → Serializer 인스턴스 생성
  • serializer_class(instance) 호출 → 쿼리셋을 JSON으로 변환
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "username", "email"]

 

쿼리셋 → Python 객체 → JSON 변환 완료!


4.  Response 객체로 변환 후 반환

  • Response(serializer.data, status=200) 실행
  • DRF의 renderer_classes 설정에 따라 JSON으로 변환
  • 클라이언트에 최종 응답 전송! 🚀

✅ 최종 흐름 정리

1. 클라이언트 요청 → APIView가 받음

2. GenericAPIView에서 queryset 조회

3. Serializer가 데이터를 JSON으로 변환

4. Response(serializer.data)를 반환하여 클라이언트에 전송


🎯 한 줄 요약

DRF는 APIView에서 요청을 받고 → GenericAPIView에서 데이터를 가져오고 → Serializer로 JSON 변환 후 Response로 반환! 🚀🔥

이제 DRF의 전체적인 동작 흐름이 한눈에 보이시죠? 😆

반응형
LIST