Django 혹은 DRF에서 제공하는 기능을 사용하다보면, 수정해야만 하는 경우가 있습니다. 서비스 전체의 응답이 아닌 특정 함수에서 404 응답을 수정하기 위한 방법입니다.

404 예외과련 Django 문서를 찾아보니 다음과 같이 raise를 통해 Http404를 발생시킵니다.

from django.http import Http404
from django.shortcuts import render
from polls.models import Poll

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404("Poll does not exist")
    return render(request, 'polls/detail.html', {'poll': p})

DRF Generic View, get_object()에서 Django get_object_or_404() 함수를 호출합니다. 그리고 이 함수에서 Http404를 일으킵니다. 그래서 try ~ except를 이용해 Http404인 경우를 캐치해 처리합니다.

from django.http import Http404
from rest_framework.generics import RetrieveAPIView
from rest_framework.response import Response

class PollDetail(RetrieveAPIView):
    queryset = Poll.objects.all()

    def get(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
        except Http404:
            return Response()  # your response
        serializer = self.get_serializer(instance)
        return Response()  # your response

동일한 방식으로 DRF에서 처리하는 NotFound에도 적용합니다.

from rest_framework.generics import ListAPIView
from rest_framework.exceptions import NotFound
from rest_framework.response import Response

class PollList(ListAPIView):
    queryset = Poll.objects.all()
    serializer_class = PollSerializer
    pagination_class = PollPagination

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        try:
            page = self.paginate_queryset(queryset)
        except NotFound:
            return Response()  # your response

        serializer = self.get_serializer(page, many=True)
        result = self.get_paginated_response(serializer.data)
        data = result.data
        return Response()  # your response