REST 프레임워크에는 다양한 미디어 유형으로 응답을 반환할 수 있는 여러 내장 렌더러 클래스가 포함되어 있습니다. 또한 고유한 사용자 정의 렌더러 정의에 대한 지원이 있어 고유한 미디어 유형을 설계할 수 있는 유연성을 제공합니다.
API를 구현할 때 다양한 포맷에 맞춰서 응답할 수 있습니다. 하나의 API 인자에 따라 같은 내용을 PDF, XLSX, JSON, HTML 등등 다양한 포맷으로 응답을 하고 싶을 때가 있겠지요. 다양한 형태의 응답 포맷을 지원하고 싶을땐 DRF의 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(),
]
기본 설정은 다음과 같으며,
# django-rest-framework/rest_framework/settings.py
DEFAULTS = {
# Base API policies
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
settings.py
의 REST_FRAMEWORK
의 DEFAULT_RENDERER_CLASSES
설정으로 오버라이딩 하면 기본 렌더러 세트를 전역적으로 사용할 수 있습니다.
# settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
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)
함수 기반의 @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)
rest_framework.response.Response
에서는 2가지 응답을 합니다.
응답 포맷을 결정하는 방법은 3가지가 있습니다.
localhost:8000/ Accept:application/json
localhost:8000/ Accept:text/html
http://localhost:8000/?format=json
http://localhost:8000/?=format=api
http://localhost:8000/.json
http://localhost:8000/.api