기계가 상호작용하는 웹 서비스는 단순한 form 데이터보다 더 복잡한 데이터를 전송하기 때문에, form 인코딩 방식보다는 더 구조화된 형식을 사용하여 데이터를 전송하는 경향이 있습니다.
— 말콤 트레디닉, Django 개발자 그룹
REST 프레임워크에는 여러 가지 내장 파서(Parser) 클래스가 포함되어 있어 다양한 미디어 유형으로 요청을 받을 수 있습니다. 또한, 사용자 정의 파서를 정의할 수 있는 기능도 제공하므로, API가 허용하는 미디어 유형을 유연하게 설계할 수 있습니다.
뷰에 대해 유효한 파서 목록은 항상 클래스 리스트로 정의됩니다. request.data에 접근할 때 REST 프레임워크는 들어오는 요청의 Content-Type 헤더를 확인하고, 해당 요청 콘텐츠를 해석할 파서를 결정합니다.
주의: 클라이언트 애플리케이션을 개발할 때는 HTTP 요청으로 데이터를 전송할 때 Content-Type 헤더를 설정하는 것을 잊지 마셔야 합니다.
Content-Type을 설정하지 않으면 대부분의 클라이언트는 기본적으로 'application/x-www-form-urlencoded'를 사용하게 됩니다. 이는 원하시는 것과 다를 수 있습니다.
예를 들어, jQuery의 .ajax() 메서드를 사용하여 JSON 인코딩된 데이터를 전송하는 경우 contentType: 'application/json' 설정을 포함시켜야 합니다.
기본 파서 세트는 DEFAULT_PARSER_CLASSES 설정을 사용하여 전역적으로 설정할 수 있습니다. 예를 들어, 아래 설정은 기본값인 JSON 또는 폼 데이터를 사용하는 대신, JSON 콘텐츠만 허용하도록 합니다.
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
}
또한, 개별 뷰나 뷰셋에 대해 사용되는 파서를 APIView 클래스 기반 뷰에서 설정할 수 있습니다.
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
"""
JSON 콘텐츠로 POST 요청을 받을 수 있는 뷰.
"""
parser_classes = [JSONParser]
def post(self, request, format=None):
return Response({'received data': request.data})
또는, 함수 기반 뷰에서 @api_view 데코레이터와 함께 @parser_classes 데코레이터를 사용할 수 있습니다.
from rest_framework.decorators import api_view
from rest_framework.decorators import parser_classes
from rest_framework.parsers import JSONParser
@api_view(['POST'])
@parser_classes([JSONParser])
def example_view(request, format=None):
"""
JSON 콘텐츠로 POST 요청을 받을 수 있는 뷰.
"""
return Response({'received data': request.data})
JSON 요청 콘텐츠를 해석합니다. request.data는 데이터 딕셔너리로 채워집니다.
application/jsonHTML 폼 콘텐츠를 해석합니다. request.data는 QueryDict로 채워집니다.
HTML 폼 데이터를 완전히 지원하려면 FormParser와 MultiPartParser를 함께 사용하는 것이 좋습니다.
application/x-www-form-urlencoded파일 업로드를 지원하는 멀티파트 HTML 폼 콘텐츠를 해석합니다. request.data와 request.FILES는 각각 QueryDict와 MultiValueDict로 채워집니다.
HTML 폼 데이터를 완전히 지원하려면 FormParser와 MultiPartParser를 함께 사용하는 것이 좋습니다.
multipart/form-data파일 업로드 콘텐츠를 원시(raw)로 해석합니다. request.data 속성은 업로드된 파일을 포함하는 하나의 키 'file'로 채워진 딕셔너리가 됩니다.
만약 FileUploadParser가 filename URL 키워드 인수를 사용하여 호출된다면, 해당 인수가 파일 이름으로 사용됩니다.
filename URL 키워드 인수가 없을 경우, 클라이언트는 HTTP 헤더의 Content-Disposition에 파일 이름을 설정해야 합니다. 예: Content-Disposition: attachment; filename=upload.jpg.
*/*참고 사항:
# views.py
class FileUploadView(views.APIView):
parser_classes = [FileUploadParser]
def put(self, request, filename, format=None):
file_obj = request.data['file']
# ...
# 업로드된 파일로 작업을 수행합니다.
# ...
return Response(status=204)
# urls.py
urlpatterns = [
# ...
re_path(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view())
]
커스텀 파서를 구현하려면 BaseParser를 상속하고 .media_type 속성을 설정한 후, .parse(self, stream, media_type, parser_context) 메서드를 구현해야 합니다.
이 메서드는 요청의 request.data 속성을 채울 데이터를 반환해야 합니다.
.parse() 메서드에 전달되는 인수는 다음과 같습니다.
stream
요청의 본문을 나타내는 스트림(stream) 같은 객체입니다.
media_type
선택 사항입니다. 제공되는 경우, 이는 들어오는 요청 콘텐츠의 미디어 유형을 나타냅니다.
요청의 Content-Type 헤더에 따라, 이것은 렌더러의 media_type 속성보다 더 구체적일 수 있으며, 미디어 유형 파라미터를 포함할 수 있습니다. 예를 들어, "text/plain; charset=utf-8"과 같은 형식입니다.
parser_context
선택 사항입니다. 제공되는 경우, 요청 콘텐츠를 해석하는 데 필요한 추가 컨텍스트가 포함된 딕셔너리입니다.
기본적으로 이 딕셔너리에는 다음 키들이 포함됩니다: view, request, args, kwargs.
다음은 요청 본문을 나타내는 문자열로 request.data 속성을 채우는 간단한 텍스트 파서의 예입니다.
class PlainTextParser(BaseParser):
"""
일반 텍스트 파서입니다.
"""
media_type = 'text/plain'
def parse(self, stream, media_type=None, parser_context=None):
"""
요청의 본문을 나타내는 문자열을 반환합니다.
"""
return stream.read()
아래는 사용할 수 있는 몇 가지 서드파티 패키지입니다.
REST framework YAML은 YAML 파싱과 렌더링을 지원합니다. 이 패키지는 이전에는 REST 프레임워크 패키지에 직접 포함되었으나, 이제는 서드파티 패키지로 지원됩니다.
pip을 사용하여 설치합니다.
$ pip install djangorestframework-yaml
REST 프레임워크 설정을 수정합니다.
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework_yaml.parsers.YAMLParser',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework_yaml.renderers.YAMLRenderer',
],
}
REST Framework XML은 간단한 비공식 XML 형식을 제공합니다. 이 패키지도 이전에는 REST 프레임워크 패키지에 직접 포함되었으나, 이제는 서드파티 패키지로 지원됩니다.
pip을 사용하여 설치합니다.
$ pip install djangorestframework-xml
REST 프레임워크 설정을 수정합니다.
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework_xml.parsers.XMLParser',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework_xml.renderers.XMLRenderer',
],
}
MessagePack은 빠르고 효율적인 바이너리 직렬화 형식입니다. Juan Riaza는 djangorestframework-msgpack 패키지를 유지 관리하고 있으며, 이 패키지는 REST 프레임워크를 위한 MessagePack 렌더러와 파서 지원을 제공합니다.
djangorestframework-camel-case는 REST 프레임워크를 위한 camel case JSON 렌더러와 파서를 제공합니다. 이 패키지를 사용하면 시리얼라이저가 Python 스타일의 언더스코어 필드 이름을 사용하면서도, API에서 Javascript 스타일의 camel case 필드 이름으로 노출될 수 있습니다. 이 패키지는 Vitaly Babiy가 유지 관리하고 있습니다.