All Articles

Django Rest Framework 활용하기 3 - APIView class

Udemy 강의를 들으면서, DRF 공식문서를 보면서, 그리고 구글링하면서 정리한 내용입니다.

Django REST Framework - Level One

The APIView class

APIView는 매우 강력한 툴이다. APIView 하나로 굉장히 많은 메소드를 사용할 수 있기 때문이다. 하지만 지금 단계에서는 APIView 클래스 기초만 연습해보고 이후 강의에서 심화된 내용을 다룰 것이다.

우선 APIView 클래스를 이용해 전체 article list에 관한 get, post 메소드를 구현해보자.

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response

from news.models import Article
from news.api.serializers import ArticleSerializer

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

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

함수 기반 api view와 대체로 코드가 비슷하지만 APIView 클래스를 사용했을 때가 좀 더 코드가 깔끔하고 메소드가 직관적이다.

'''
import 코드 생략
'''
# 앞서 함수 기반 api view 구현에서 썼던 try, except 대신 get_object_or_404를 import 해서 사용
from rest_framework.generics import get_object_or_404

'''
import 코드 생략
'''

class ArticleDetailAPIView(APIView):
  # get_object 메소드로 우선 존재하는 인스턴스인지 판단해준다.
  # 인스턴스가 존재한다면 그것을 리턴한다.
  # 여기서 리턴한 인스턴스(article)는 아래 3개 메소드에서 공통으로 사용한다.
  def get_object(self, pk):
    article = get_object_or_404(Article, pk = pk)
    return article

  # 이하 코드는 함수 기반 api view와 유사
  # 모든 메소드에서 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)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data)
    return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)

  def delete(self, request, pk):
    article = self.get_object(pk)
    article.delete()
    return Response(status = status.HTTP_204_NO_CONTENT)

함수 기반 api view와 동일한 결과를 출력한다.

class based list view

article list 출력

class based detail view

pk값을 slug로 받아 특정 article 출력

class based detail post

새 article 생성