Post

Django REST Framework Class Based View (CBV)

Django REST Framework에서 Class Based View를 활용한 구조적이고 효율적인 API 개발 가이드.

Django REST Framework Class Based View (CBV)

Django REST Framework(DRF)는 강력한 API 개발 도구를 제공하며, 그중에서도 Class Based View(CBV)는 API 개발을 구조적이고 효율적으로 만드는 데 중요한 역할을 합니다.

Class Based View란?

Django와 DRF의 View는 크게 두 가지 방식으로 작성할 수 있습니다:

  1. 함수형 뷰 (FBV): 단순한 함수 형태로 정의.
  2. 클래스형 뷰 (CBV): 클래스를 사용하여 HTTP 메서드별로 로직을 나눔.

DRF에서는 CBV를 사용하면 코드의 재사용성과 유지보수성을 크게 향상시킬 수 있습니다.

CBV의 주요 특징

  • HTTP 메서드별 함수 정의:
    • get(), post(), put(), delete() 등의 메서드를 정의하여 각각의 요청을 처리.
  • 코드 재사용성:
    • 반복되는 로직을 클래스와 메서드로 구조화.
  • 다양한 내장 클래스 제공:
    • APIView, GenericAPIView, Mixin, ViewSets 등으로 API 개발을 간소화.

CBV의 구성 요소

1. APIView

APIView는 DRF의 모든 CBV의 기반 클래스입니다. HTTP 요청을 처리하고 응답을 생성하는 기본 기능을 제공합니다.

코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer

class ArticleListAPIView(APIView):
    def get(self, request):
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

특징

  • get(): 모든 Article 객체를 조회.
  • post(): 새로운 Article 객체를 생성.

URL 패턴 설정

1
2
3
4
5
6
from django.urls import path
from .views import ArticleListAPIView

urlpatterns = [
    path('', ArticleListAPIView.as_view(), name='article_list'),
]
  • as_view(): 클래스 기반 뷰를 호출 가능한 함수로 변환.

2. ArticleDetailAPIView

객체 단위로 데이터를 처리하는 API를 구현할 때 사용합니다.

코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.shortcuts import get_object_or_404

class ArticleDetailAPIView(APIView):
    def get_object(self, pk):
        return get_object_or_404(Article, pk=pk)

    def get(self, request, pk):
        article = self.get_object(pk)
        serializer = ArticleSerializer(article)
        return Response(serializer.data)

    def put(self, request, pk):
        article = self.get_object(pk)
        serializer = ArticleSerializer(article, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

    def delete(self, request, pk):
        article = self.get_object(pk)
        article.delete()
        return Response({"message": f"Article {pk} deleted"}, status=status.HTTP_200_OK)

특징

  • get(): 특정 객체 조회.
  • put(): 특정 객체 수정.
  • delete(): 특정 객체 삭제.

URL 패턴 설정

1
2
3
urlpatterns = [
    path('<int:pk>/', ArticleDetailAPIView.as_view(), name='article_detail'),
]

CBV의 장점과 특징 정리

장점

  1. 구조적 코드: 메서드 단위로 로직을 나누어 가독성과 유지보수가 용이.
  2. 코드 재사용성: 공통 로직을 부모 클래스에 정의하여 여러 뷰에서 재사용 가능.
  3. 확장성: 새로운 요구사항에 맞게 클래스 확장 가능.

CBV와 FBV 비교

특징CBVFBV
가독성구조적이고 명확함간단한 로직에서 직관적
재사용성높은 재사용성제한적
유지보수복잡한 프로젝트에서 용이단순 프로젝트에서 적합
학습 난이도상대적으로 높음상대적으로 낮음

추가적인 DRF CBV 도구

GenericAPIView

GenericAPIViewAPIView를 확장하여 더욱 간편한 API 구현을 지원합니다. queryset, serializer_class 등의 속성과 메서드를 제공하여 공통 작업을 간소화합니다.

코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from rest_framework.generics import GenericAPIView
from .models import Article
from .serializers import ArticleSerializer

class ArticleListCreateView(GenericAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    def get(self, request):
        serializer = self.get_serializer(self.get_queryset(), many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

Mixins

GenericAPIView와 함께 사용하여 CRUD 작업을 간소화합니다.

코드 예제

1
2
3
4
5
6
7
8
9
10
11
from rest_framework.mixins import ListModelMixin, CreateModelMixin

class ArticleListMixinView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

대표적인 Concrete Views

Concrete Views는 GenericAPIView와 Mixins를 조합하여 자주 사용하는 작업을 간소화한 클래스입니다. 다음은 주요 Concrete Views와 그 역할입니다:

클래스 이름역할
ListAPIView객체 리스트를 반환하는 API
CreateAPIView새로운 객체를 생성하는 API
RetrieveAPIView특정 객체를 조회하는 API
UpdateAPIView특정 객체를 수정하는 API
DestroyAPIView특정 객체를 삭제하는 API
ListCreateAPIView객체 리스트 조회와 생성 기능을 동시에 제공
RetrieveUpdateAPIView특정 객체 조회와 수정 기능을 동시에 제공
RetrieveDestroyAPIView특정 객체 조회와 삭제 기능을 동시에 제공
RetrieveUpdateDestroyAPIView특정 객체 조회, 수정, 삭제를 모두 제공

코드 예제: ListCreateAPIView

1
2
3
4
5
6
7
from rest_framework.generics import ListCreateAPIView
from .models import Article
from .serializers import ArticleSerializer

class ArticleListCreateAPIView(ListCreateAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

코드 예제: RetrieveUpdateDestroyAPIView

1
2
3
4
5
6
7
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .models import Article
from .serializers import ArticleSerializer

class ArticleDetailAPIView(RetrieveUpdateDestroyAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
This post is licensed under CC BY 4.0 by the author.