본문 바로가기
Django/Django REST framework

7. Parsers

by hyun-am 2021. 6. 29.

Parser

시스템 상호 작용 웹 서비스는 단순한 형식보다 복잡한 데이터를 전송하기 때문에 form-encoded보다 더 구조화된 form을 사용합니다.

REST 프레임워크에는 다양한 미디어 유형의 요청을 수락할 수 있는 기본 파서 클래스가 다수 포함되어 있습니다. 또한 사용자 정의 구문 분석기를 정의할 수 있어 API에서 허용하는 media types를 유연하게 설계할 수 있습니다.


parser 결정하는 방법

view에 유효한 parser 셋은 항상 클래스 목록으로 정의됩니다. request.data에 액세스하면 DRF는 들어오는 요청의 Content-Type 헤더를 검사하고 요청내용을 파싱할 파서를 결정합니다.

참고 : 클라이언트 응용 프로그램을 개발할 때는 HTTP request로 데이터를 전송할 때 항상 content-type 헤더를 설정해야 합니다.

Content-type을 설정하지 않으면 대부분의 클라이언트는 기본적으로 'application/x-www-form-urlencoded'를 사용하게 됩니다. 이것은 사용자가 원하는 것과 다를 수 있습니다.

예를 들어 .ajax() 메서드와 함께 jQuery를 사용하여 json 인코딩 데이터를 보내는 경우 contentType : 'application/json' 설정을 입력해야 합니다.

parsers 설정하기

기본 파서 셋을 DEFAULT_PARSER_CLASES 설정을 사용하여 전체적으로 설정할 수 있습니다. 예를 들어, 다음 설정은 기본 JSON 또는 양식 데이터 대신 JSON 컨텐츠가 포함된 요청만 허용합니다.

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ]
}

또한 APIView CBV를 사용하여 개별 view 또는 viewset에 사용되는 파서를 설정할 수도 있습니다.

from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    """
    A view that can accept POST requests with JSON content.
    """
    parser_classes = [JSONParser]

    def post(self, request, format=None):
        return Response({'received data': request.data})

또는 FBV와 함께 @api_view decorator를 사용하는 경우.

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):
    """
    A view that can accept POST requests with JSON content.
    """
    return Response({'received data': request.data})

API Reference

JSONParser

JSON 요청 컨텐츠를 파싱합니다. request.data는 데이터 딕셔너리로 채워집니다.

.media_type : application/json

FormParser

HTML form 컨텐츠를 파싱합니다. request.data는 데이터 QueryDict로 채워집니다.

HTML form 데이터를 완벽하게 지원하려면 일반적으로 FormParser과 MultiPartParser를 같이 사용해야 합니다.

.media_type: application/x-www-form-urlencoded

MultiPartParser

파일 업로드를 지원하는 멀티파트 HTML form 컨텐츠를 파싱합니다. 두개의 request.data 모두 QueryDict로 채워집니다.

HTML form 데이터를 완벽하게 지원하려면 일반적으로 FormParser과 MultiPartParser를 함께 사용해야합니다.

.media_type: multipart/form-data

FileUploadParser

raw 파일 업로드 컨텐츠를 파싱합니다. request.data 속성은 업로드된 파일이 포함된 단일 키 'file'이 있는 딕셔너리가 됩니다.

FileUploadParser와 함께 사용되는 view가 filename URL 키워드 아규먼트와 함께 호출되는 경우 해당 아규먼트가 filename으로 사용됩니다.

URL 키워드 아규먼트 없이 filename이 호출되는 경우 클라이언트는 content-Disposition HTTP header에서 filename을 설정해야합니다. 예시 : Content-Disposition : attachment; filename=upload.jpg입니다.

.media_type: */*

참고사항 :

  • FileUploadParser는 파일을 raw data 요청으로 업로드할 수 있는 네이티브 클라이언트에서 사용하기 위한 것입니다. 웹 기반 업로드의 경우 또는 멀티 파트 업로드가 지원되는 네이티브 클라이언트의 경우 MultiPartParser를 대신 사용해야 합니다.
  • 이 파서의 media_type은 모든 컨텐츠 타입과 일치하므로 일반적으로 FileUploadParser만 APIView에 설정된 파서여야합니다.
  • FileUploadParser는 Django의 표준 FILE_UPLOAD_HANDLERS를 준수합니다. 핸들러 설정 및 request.upload_handlers 애트리뷰트를. 자세한 내용은 장고 문서에서 확인할 수 있습니다.

장고 문서 링크 : https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/#upload-handlers

 

File Uploads | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

Basic usage example:

# views.py
class FileUploadView(views.APIView):
    parser_classes = [FileUploadParser]

    def put(self, request, filename, format=None):
        file_obj = request.data['file']
        # ...
        # do some stuff with uploaded file
        # ...
        return Response(status=204)

# urls.py
urlpatterns = [
    # ...
    re_path(r'^upload/(?P<filename>[^/]+)$', FileUploadView.as_view())
]

 

Custom parsers

사용자 정의 파서를 구현하려면 BaseParser를 재정의하고, .media_type 속성을 설정한 다음 .parser(self, stream, media_type, parser_context) 메서드를 구현해야 합니다.

메서드는 request.data 속성을 채우는 데 사용할 데이터를 반환해야 합니다.

.parser()에 있는 아규먼트들은 다음과 같습니다.

stream

request body를 나타내는 스트림과 같은 개체입니다.

media_type

선택사항입니다. 이 media type은 request content의 미디어 타입입니다.

request의 Content-Type : 헤더에 따라 렌더러의 media_type 속성보다 구체적일 수 있으며 media_type 매개 변수를 포함할 수 있습니다. 예를 들어 "text/plain; charset=utf-8"과 같은.

parser_context

선택사항입니다. 만약에 제공된 경우 이 아규먼트는 request content를 파싱하는 데 필요한 추가 컨텍스트를 포함하는 딕셔너리가 됩니다.

기본적으로 여기에는 view, request, args, kwargs등의 키가 포합됩니다.

예시 코드

다음은 request.data 속성을 request body를 나타내는 문자열로 채우는 plaintext 파서의 예시 입니다.

 

class PlainTextParser(BaseParser):
    """
    Plain text parser.
    """
    media_type = 'text/plain'

    def parse(self, stream, media_type=None, parser_context=None):
        """
        Simply return a string representing the body of the request.
        """
        return stream.read()

 

참고링크 : https://www.django-rest-framework.org/api-guide/parsers/#notes

 

Parsers - Django REST framework

 

www.django-rest-framework.org

 

'Django > Django REST framework' 카테고리의 다른 글

9-1. Serializers  (0) 2021.07.15
8. Renderers  (0) 2021.07.07
6. Routers  (0) 2021.06.28
5. ViewSets  (0) 2021.06.26
4-2 Generic Views (Mixin,Concrete)  (0) 2021.06.23

댓글