Парсеры¶
Взаимодействующие с машинами веб-сервисы, как правило, используют более структурированные форматы для отправки данных, чем кодированные формы, поскольку они отправляют более сложные данные, чем простые формы
‒ Malcom Tredinnick, Django developers group
REST framework включает в себя несколько встроенных классов парсеров, которые позволяют принимать запросы с различными типами медиа. Также имеется поддержка определения собственных парсеров, что дает вам гибкость в определении типов медиа, которые принимает ваш API.
Как определяется синтаксический анализатор¶
Набор допустимых парсеров для представления всегда определяется как список классов.  При обращении к request.data фреймворк REST изучает заголовок Content-Type во входящем запросе и определяет, какой парсер использовать для разбора содержимого запроса.
Примечание : При разработке клиентских приложений всегда помните, что вы должны убедиться, что вы устанавливаете заголовок Content-Type при отправке данных в HTTP запросе.
Если вы не зададите тип содержимого, большинство клиентов по умолчанию будут использовать 'application/x-www-form-urlencoded' , что может быть не то, что вы хотели.
Например, если вы отправляете данные в кодировке json с помощью jQuery с параметром .ajax() method <https://api.jquery.com/jQuery.ajax/>`_** , вы должны обязательно включить параметр ``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):
    """
    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})
Или, если вы используете декоратор @api_view с представлениями, основанными на функциях.
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¶
JSONParser¶
Разбирает JSON содержимое запроса. request.data будет заполнен словарем данных.
.media_type : application/json
FormParser¶
Разбирает содержимое HTML-формы.  request.data будет заполнено QueryDict данными.
Как правило, для полной поддержки данных HTML-формы необходимо использовать и FormParser, и MultiPartParser вместе.
.media_type : application/x-www-form-urlencoded
MultiPartParser¶
Разбирает содержимое многочастной HTML-формы, которая поддерживает загрузку файлов.  Оба request.data будут заполнены QueryDict.
Как правило, для полной поддержки данных HTML-формы необходимо использовать и FormParser, и MultiPartParser вместе.
.media_type : multipart/form-data
FileUploadParser¶
Разбирает необработанное содержимое загруженного файла.  Свойство request.data будет представлять собой словарь с единственным ключом 'file', содержащим загруженный файл.
Если представление, используемое с FileUploadParser, вызывается с аргументом ключевого слова URL filename, то этот аргумент будет использоваться в качестве имени файла.
Если он вызывается без ключевого аргумента filename URL, то клиент должен задать имя файла в заголовке Content-Disposition HTTP.  Например, Content-Disposition: attachment; filename=upload.jpg.
.media_type : */*
Примечания:¶
- Значение - FileUploadParserпредназначено для использования с собственными клиентами, которые могут загружать файл как запрос необработанных данных. Для загрузки через Интернет или для собственных клиентов с поддержкой многокомпонентной загрузки следует использовать- MultiPartParser.
- Поскольку этот парсер - media_typeсоответствует любому типу содержимого,- FileUploadParserобычно должен быть единственным парсером, установленным в представлении API.
- FileUploadParserсоблюдает стандартную настройку Django- FILE_UPLOAD_HANDLERS, а также атрибут- request.upload_handlers. См. Django documentation для более подробной информации.
Основной пример использования:¶
# 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())
]
Пользовательские синтаксические анализаторы¶
Для реализации пользовательского парсера необходимо переопределить BaseParser , установить свойство .media_type и реализовать метод .parse(self, stream, media_type, parser_context).
Метод должен вернуть данные, которые будут использованы для заполнения свойства request.data.
Аргументами, передаваемыми в .parse(), являются:
Потокоподобный объект, представляющий тело запроса.
Необязательно. Если указано, это тип носителя содержимого входящего запроса.
В зависимости от заголовка запроса Content-Type:, он может быть более конкретным, чем атрибут рендерера media_type, и может включать параметры медиатипа.  Например, "text/plain; charset=utf-8".
Необязательный. Если этот аргумент указан, то он будет представлять собой словарь, содержащий любой дополнительный контекст, который может потребоваться для разбора содержимого запроса.
По умолчанию сюда входят следующие ключи: view , request , args , kwargs.
Пример¶
Ниже приведен пример парсера обычного текста, который заполнит свойство request.data строкой, представляющей тело запроса.
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()
Пакеты сторонних производителей¶
Также доступны следующие пакеты сторонних производителей.
YAML¶
REST framework YAML обеспечивает поддержку парсинга и рендеринга YAML. Ранее он был включен непосредственно в пакет REST framework, а теперь поддерживается как сторонний пакет.
Установите с помощью pip.
$ pip install djangorestframework-yaml
Измените настройки фреймворка REST.
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_yaml.parsers.YAMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_yaml.renderers.YAMLRenderer',
    ],
}
XML¶
REST Framework XML предоставляет простой неформальный формат XML. Ранее он был включен непосредственно в пакет REST framework, а теперь вместо этого поддерживается как сторонний пакет.
Установите с помощью 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¶
MessagePack - это быстрый, эффективный формат двоичной сериализации. Juan Riaza поддерживает пакет djangorestframework-msgpack, который обеспечивает поддержку MessagePack renderer и parser для REST framework.
CamelCase JSON¶
djangorestframework-camel-case предоставляет рендереры и парсеры JSON в верблюжьем регистре для фреймворка REST. Это позволяет сериализаторам использовать имена полей с подчеркиванием в стиле Python, но отображать их в API как имена полей в верблюжьем регистре в стиле Javascript. Поддерживается Vitaly Babiy.