Renderer
- 같은 Endpoint에서 요청받은 타입에 맞춰, 다양한 응답포맷을 지원
- Content-Type, URL의 방법을 통해 Renderer 지정 가능
기본 지원되는 Renderer
JSONRenderer (디폴트 지정) : json.dumps를 통한 JSON 직렬화
- media_type -> application/json, format -> json
BrowsableAPIRenderer (디폴트 지정) : self-document HTML 렌더링
- media_type -> text/html, format -> api
TemplateHTMLRenderer : 지정 템플릿을 통한 렌더링
- media_type -> text/html, format -> api
- Response에서 template_name 인자 지정 필요
- API 서버라고 해서 모든 응답을 JSON으로 받지 않아도. 경우에 따라서 HTML 응답을 받을 수도. (Server Side Rendering?)
TemplateHTMLRenderer
템플릿을 통해 Render를 수행하기에 별도의 Serializer가 불필요
class PostDetail(RetrieveAPIView):
queryset = Post.objects.all()
renderer_classes = [TemplateHTMLRenderer]
template_name = 'blog/post_detail.html'
def get(self, request, *args, **kwargs):
return Response({
'post': self.get_object(),
})
이 외에도 다양한 Renderer
StaticHTMLRenderer
- 미리 렌더링된 HTML을 반환. Response 객체 생성 시에 HTML 문자열을 직접 지정
@api_view(["GET"])
@renderer_classes([StaticHTMLRenderer])
def static_view(request):
html = """<html><body>example</body></html>"""
return Response(html)
써드파티 Renderer
drf-renderer-xlsx (내부적으로 openpyxl 활용, application/xlsx, 포맷: xlsx)
djangorestframework-yaml
djangorestframework-xml
djangorestframework-jsonp
djangorestframework-msgpack
djangorestframework-csv
rest-framework-latex
Renderer 선택
Renderer 클래스 리스트 지정하기
전역 지정
- settings -> REST-FRAMEWORK -> DEFAULT_RENDERER_CLASSES 리스트에 문자열로 지정
APIView 마다 지정
- queryset, serializer_class와 더불어, renderer_classes 리스트
@api_view 마다 지정
Renderer 이외의 다른 속성들도 마찬가지 방법으로 설정
Response의 기본 2가지 유형의 응답 포맷
rest_framework.response.Response
- api : API Endpoint에 브라우저를 통해 접근할 때, 웹 UI로 조회 가능
- json : 보통의 API 접근
응답 포맷은 어떻게 결정되는가?
Accept 헤더
- Accept: application/json
- Accept: text/html
2. DefaultRouter에서는 기본 지원
- router.urls에서의 URL Patterns
[
<URLPattern '^post/$' [name='post-list']>,
<URLPattern '^post\.(?P<format>[a-z0-9]+)/?$' [name='post-list']>,
<URLPattern '^post/(?P<pk>[^/.]+)/$' [name='post-detail']>,
<URLPattern '^post/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='post-detail']>,
<URLPattern '^$' [name='api-root']>,
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
]
views.py
from rest_framework.decorators import api_view
@api_view(['GET'])
def hello(request, format=None):
return Response([])
urls.py
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = format_suffix_patterns([
path('hello/', views.hello),
])
생성된 URL Patterns
[
<URLPattern 'hello/'>,
<URLPattern 'hello<drf_format_suffix:format>'>,
]
- http :8000/ Accept:application/json
- http :8000/?format=json
- http :8000/.json
- http :8000/ Accept:text/html
- http :8000/?format=api
- http :8000/.api