파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 강의를 듣고 정리한 글입니다.
API를 구현할 때 다양한 포맷에 맞춰서 응답할 수 있다.
하나의 API에서 인자에 따라 같은 내용의 PDF, XLSX, JSON, HTML 등 다양한 포맷으로 응답을 하고 싶을 수도 있을 것이다.
DRF의 Renderer를 이용하면 다양한 형태의 응답 포맷을 지원할 수 있다.
같은 Endpoint에서 요청받은 타입에 맞춰, 다양한 응답포맷을 지원
Content-Type, URL의 방법을 통해 Renderer 지정 가능
템플릿을 통해 Render를 수행하기에 별도의 Serializer가 불필요
# https://www.django-rest-framework.org/topics/html-and-forms/
from rest_framework.renderers import TemplateHTMLRenderer
class PostDetailAPIView(RetrieveAPIView):
queryset = Post.objects.all()
renderer_classes = [TemplateHTMLRenderer] # 1
template_name = 'blog/post_detail.html' # 2
def get(self, request, *args, **kwargs):
return Response({
'post': self.get_object(),
})
# 위에 1, 2번을 빼고, self.get_object()를 serializer를 통한 직렬화 이후 Response로 넘기면 json응답으로 됨
# myapp/urls.py에 아래를 추가
urlpatterns = [
# ...
path('mypost/<int:pk>/', views.PostDetailAPIView.as_view())
]
연습하기
StaticHTMLRenderer
→ 미리 렌더링된 HTML을 반환. Response 객체 생성 시에 HTML문자열을 직접 지정
@api_view(["GET"])
@renderer_classes([StaticHTMLRenderer])
def static_view(request):
html = """<html><body>example</body></html>"""
return Response(html)
추가로, AdminRenderer, HTMLFormRenderer, MultiPartRenderer 등이 지원됨
Renderer 이외의 다른 속성들도 마찬가지 방법으로 설정
http://localhost:8000/resource.api
http://localhost:8000/resource.json
http://localhost:8000/resource/?format=json
application/json
text/html
?format=json
?format=api
.json
.api
[
<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']>
]
함수 기반 뷰에서는 URL Captured Values는 Keyword Arguments를 통해 전달됩니다. 즉, format인자를 받도록 설정했다면 format인자를 추가해주세요.
from rest_framework.decorators import api_view
@api_view(['GET'])
def hello(request, format=None):
return Response([])
실제 Router를 통해서 format인자가 붙은 urlpattern이 추가되었는데, Router를 쓰지 않고도 추가하고싶다면 아래와 같이 format_suffix_patterns를 이용해서 format을 지원하도록 추가할 수 있다.
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = format_suffix_patterns([
path('hello/', views.hello),
])
[
<URLPattern 'hello/'>,
<URLPattern 'hello<drf_format_suffix:**format**>'>,
]
json 형식 요구
http http://localhost:8000/ Accept:application/json
→ 커스텀 헤더를 정해준다.http http://localhost:8000/?format=json
http http://localhost:8000/.json
html 요구
http http://localhost:8000/ Accept:text/html
http http://localhost:8000/?format=api
http http://localhost:8000/.api