(DRF) Renderer 를 통한 다양한 응답

duo2208·2022년 1월 31일
1

Django

목록 보기
16/23
post-thumbnail
🚀 (DRF API Guide) Renderer
REST 프레임워크에는 다양한 미디어 유형으로 응답을 반환할 수 있는 여러 내장 렌더러 클래스가 포함되어 있습니다. 또한 고유한 사용자 정의 렌더러 정의에 대한 지원이 있어 고유한 미디어 유형을 설계할 수 있는 유연성을 제공합니다.

Renderer


API를 구현할 때 다양한 포맷에 맞춰서 응답할 수 있습니다. 하나의 API 인자에 따라 같은 내용을 PDF, XLSX, JSON, HTML 등등 다양한 포맷으로 응답을 하고 싶을 때가 있겠지요. 다양한 형태의 응답 포맷을 지원하고 싶을땐 DRF의 Renderer 를 이용하면 됩니다.

기본으로 지원되는 Renderer

  • JsonRenderer (default)
    ›› json.dumps 를 통한 JSON 직렬화.
    ›› media_type → application/json
    ›› format → json

  • BrowsableAPIRenderer (default)
    ›› self-document HTML 을 통한 렌더링.
    ›› media_type → text/html
    ›› format → api

  • TemplateHTMLRenderer
    ›› 지정 템플릿을 통한 렌더링.
    ›› media_type → text/html
    ›› format → api
    ›› Response 에서 template_name 인자 지정 필요.
    ›› API 서버라고 해서 모든 응답을 JSON으로 받지 않아도 된다. 경우에 따라서 HTML 응답을 받을 수도 있다.

# views.py
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.generics import RetrieveAPIView

class PostDetailAPIView(RetrieveAPIView):
	queryset = Post.objects.all()
	renderer_classes = [TemplateHTMLRenderer]	# 템플릿을 통해 Render를 수행함으로 별도의 Serializer 가 불필요.
 	template_name = 'blog/post_detail.html'
    
 	def get(self, request, *args, **kwargs):
		return response({
  			'post': post,
  		})
# urls.py

urlpatterns = [
	...
 	path('mypost/<int:pk>/', views.PostDetailAPIView.as_view(),
]

그 외의 Renderer

  • StaticHTMLRenderer
  • AdminRenderer
  • MultiPartRenderer

써드파티 Renderer

  • drf-renderer-xlsx
  • djangorestframework-yaml
  • djangorestframework-xml
  • djangorestframework-jsonp
  • djangorestframework-msgpack
  • djangorestframework-csv
  • rest-framework-latex



Renderer 선택


Renderer 클래스 리스트 지정하기

(1) 전역 지정

기본 설정은 다음과 같으며,

# django-rest-framework/rest_framework/settings.py 
DEFAULTS = {
    # Base API policies
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],

settings.pyREST_FRAMEWORKDEFAULT_RENDERER_CLASSES 설정으로 오버라이딩 하면 기본 렌더러 세트를 전역적으로 사용할 수 있습니다.

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}

(2) APIView 마다 지정

APIView 클래스 기반 뷰를 사용하여 개별 뷰 또는 뷰셋에 사용되는 렌더러를 설정 할 수도 있습니다.

from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer
from rest_framework.responses import Response
from rest_framework.views import APIView

""" a view that returns the count of active users in JSON. """
class UserCountView(APIView):
	renderer_class = [JSONRenderer]
  
	def get(self, request, format=None):
		user_count = User.objects.filter(activate=True).count
  		content = {'user_count': user_count}
		return Response(content)

(3) @api_view 마다 지정

함수 기반의 @api_view 데코레이터를 사용할 수도 있습니다.


@api_view(['GET'])
def user_count_view(request, format=None):
	user_count = User.objects.filter(active=True).count()
	content = {'user_count': user_count}
	return Response(content)

Response 의 응답 포맷

rest_framework.response.Response 에서는 2가지 응답을 합니다.

  • json : 보통의 API 접근.
  • api : API Endpoint 에 브라우저를 통해 접근. 웹 UI로 조회 가능.

응답 포맷을 결정하는 방법은 3가지가 있습니다.

  • Accept 헤더
localhost:8000/ Accept:application/json
localhost:8000/ Accept:text/html
  • GET 인자 format
http://localhost:8000/?format=json
http://localhost:8000/?=format=api
  • URL Captured Values 에서의 format 인자
http://localhost:8000/.json
http://localhost:8000/.api

📌 참고 출처

0개의 댓글