Рендереры
Рендереры
Прежде чем экземпляр
TemplateResponse
будет возвращен клиенту, он должен быть отрендерен. Процесс рендеринга принимает промежуточное представление шаблона и контекста и превращает его в конечный поток байтов, который может быть передан клиенту.
DRF включает ряд встроенных классов Renderer, которые позволяют возвращать ответы с различными типами медиа. Также имеется поддержка определения собственных пользовательских рендереров, что дает вам гибкость в разработке собственных типов медиа.
Как определяется рендерер
Набор допустимых рендерингов для представления всегда определяется как список классов. При входе в представление DRF будет выполнять согласование содержимого входящего запроса и определять наиболее подходящий рендерер для удовлетворения запроса.
Основной процесс согласования содержимого включает в себя изучение заголовка Accept
запроса, чтобы определить, какие типы медиа ожидаются в ответе. По желанию, суффиксы формата в URL могут быть использованы для явного запроса определенного представления. Например, URL http://example.com/api/users_count.json
может быть конечной точкой, которая всегда возвращает данные в формате JSON.
Для получения дополнительной информации смотрите документацию по согласованию контента.
Установка рендереров
Набор рендеров по умолчанию можно задать глобально, используя параметр DEFAULT_RENDERER_CLASSES
. Например, следующие настройки будут использовать JSON
в качестве основного типа медиа, а также включать API самоописания.
Вы также можете установить рендереры, используемые для отдельного представления или набора представлений, используя представления на основе класса APIView
.
Или, если вы используете декоратор @api_view
с представлениями, основанными на функциях.
Упорядочивание классов рендеринга
Важно при определении классов рендеринга для вашего API подумать о том, какой приоритет вы хотите присвоить каждому типу медиа. Если клиент недоопределяет представления, которые он может принимать, например, посылает заголовок Accept: */*
заголовок, или вообще не включает заголовок Accept
, то DRF выберет первый рендерер в списке для использования в ответе.
Например, если ваш API обслуживает JSON-ответы и HTML-просмотр, вы можете сделать JSONRenderer
рендерером по умолчанию, чтобы отправлять JSON
ответы клиентам, которые не указывают заголовок Accept
.
Если ваш API включает представления, которые могут обслуживать как обычные веб-страницы, так и ответы API в зависимости от запроса, то вы можете сделать TemplateHTMLRenderer
рендерером по умолчанию, чтобы хорошо работать со старыми браузерами, которые отправляют broken accept headers.
API Reference
JSONRenderer
Переводит данные запроса в JSON
, используя кодировку utf-8
.
Обратите внимание, что стиль по умолчанию включает символы юникода и отображает ответ, используя компактный стиль без лишних пробелов:
Клиент может дополнительно включить параметр медиатипа 'indent'
, в этом случае возвращаемый JSON
будет иметь отступ. Например, Accept: application/json; indent=4
.
Стиль кодировки JSON по умолчанию может быть изменен с помощью ключей настроек UNICODE_JSON
и COMPACT_JSON
.
.media_type: application/json
.
.format: 'json'
.
.charset: None
.
TemplateHTMLRenderer
Рендерит данные в HTML, используя стандартный шаблонный рендеринг Django. В отличие от других рендерингов, данные, передаваемые в Response
, не нужно сериализовать. Также, в отличие от других рендереров, вы можете включить аргумент template_name
при создании Response
.
TemplateHTMLRenderer создаст RequestContext
, используя response.data
в качестве диктанта контекста, и определит имя шаблона, который будет использоваться для рендеринга контекста.
Примечание: При использовании с представлением, которое использует сериализатор, Response
, отправленный для рендеринга, может не быть словарем и должен быть обернут в dict
перед возвратом, чтобы TemplateHTMLRenderer
смог его отрендерить. Например:
Имя шаблона определяется (в порядке предпочтения):
Явный аргумент
template_name
, передаваемый в ответ.Явный атрибут
.template_name
, установленный для этого класса.Результат вызова
view.get_template_names()
.
Пример представления, использующего TemplateHTMLRenderer
:
Вы можете использовать TemplateHTMLRenderer
либо для возврата обычных HTML-страниц с помощью DRF, либо для возврата HTML и API ответов с одной конечной точки.
Если вы создаете сайты, использующие TemplateHTMLRenderer
наряду с другими классами рендереров, вам следует рассмотреть возможность включения TemplateHTMLRenderer
в качестве первого класса в список renderer_classes
, чтобы он был приоритетным даже для браузеров, которые посылают плохо сформированные заголовки ACCEPT:
.
Дополнительные примеры использования TemplateHTMLRenderer
смотрите в HTML & Forms Topic Page.
.media_type: text/html
.
.format: 'html'
.
.charset: utf-8
См. также: StaticHTMLRenderer
StaticHTMLRenderer
Простой рендерер, который просто возвращает предварительно отрендеренный HTML. В отличие от других рендереров, данные, передаваемые в объект ответа, должны быть строкой, представляющей возвращаемое содержимое.
Пример представления, использующего StaticHTMLRenderer
:
Вы можете использовать StaticHTMLRenderer
либо для возврата обычных HTML-страниц с помощью DRF, либо для возврата HTML- и API-ответов с одной конечной точки.
.media_type: text/html
.
.format: 'html'
.
.charset: utf-8
См. также: TemplateHTMLRenderer
.
BrowsableAPIRenderer
Рендерит данные в HTML для Browsable API:
Этот рендерер определяет, какой другой рендерер имел бы наивысший приоритет, и использует его для отображения ответа в стиле API на HTML-странице.
.media_type: text/html
.
.format: 'api'
.
.charset: utf-8
.template: 'rest_framework/api.html'
.
Настройка BrowsableAPIRenderer
По умолчанию содержимое ответа будет отображаться рендерером с наивысшим приоритетом, кроме BrowsableAPIRenderer
. Если вам нужно настроить это поведение, например, использовать HTML в качестве формата возврата по умолчанию, но использовать JSON в Web-интерфейсе API, вы можете сделать это, переопределив метод get_default_renderer()
. Например:
AdminRenderer
Рендерит данные в HTML для отображения в стиле администратора:
Этот рендерер подходит для веб-интерфейсов в стиле CRUD, которые также должны представлять удобный интерфейс для управления данными.
Обратите внимание, что представления, которые имеют вложенные или списковые сериализаторы для своего ввода, не будут хорошо работать с AdminRenderer
, так как HTML-формы не могут должным образом поддерживать их.
Примечание: AdminRenderer
способен включать ссылки на детальные страницы только в том случае, если в данных присутствует правильно настроенный атрибут URL_FIELD_NAME
(по умолчанию url
). Для HyperlinkedModelSerializer
так и будет, но для классов ModelSerializer
или простого Serializer
вам нужно будет убедиться, что поле включено явно. Например, здесь мы используем метод модели get_absolute_url
:
.media_type: text/html
.
.format: 'admin'
.
.charset: utf-8
.template: 'rest_framework/admin.html'
.
HTMLFormRenderer
Переводит данные, возвращаемые сериализатором, в форму HTML. Вывод этого рендерера не включает заключающие теги <form>
, скрытый CSRF-вход или какие-либо кнопки отправки.
Этот рендерер не предназначен для прямого использования, но может быть использован в шаблонах путем передачи экземпляра сериализатора в тег шаблона render_form
.
Для получения дополнительной информации смотрите документацию HTML & Forms.
.media_type: text/html
.
.format: 'format'
.
.charset: utf-8
.template: 'rest_framework/horizontal/form.html'
.
MultiPartRenderer
Этот рендерер используется для рендеринга данных многочастной формы HTML. Он не подходит для рендеринга ответов, а используется для создания тестовых запросов, используя тестовый клиент и фабрику тестовых запросов DRF.
.media_type: multipart/form-data; border=BoUnDaRyStRiNg
.
.format: 'multipart'
.
.charset: utf-8
Пользовательские рендеры
Для реализации пользовательского рендерера необходимо отнаследоваться от BaseRenderer
, установить свойства .media_type
и .format
и реализовать метод .render(self, data, accepted_media_type=None, renderer_context=None)
.
Метод должен возвращать строку байт, которая будет использоваться в качестве тела ответа HTTP.
Аргументы, передаваемые методу .render()
, следующие:
data
data
Данные запроса, заданные инстанцией Response()
.
accepted_media_type=None
accepted_media_type=None
Дополнительно. Если указано, то это принятый тип носителя, определенный на этапе согласования содержимого.
В зависимости от заголовка Accept:
клиента, он может быть более конкретным, чем атрибут media_type
рендерера, и может включать параметры типа медиа. Например, 'application/json; nested=true'
.
renderer_context=None
renderer_context=None
Опционально. Если предоставляется, то это словарь контекстной информации, предоставляемой представлением.
По умолчанию сюда входят следующие ключи: view
, request
, response
, args
, kwargs
.
Пример
Ниже приведен пример рендеринга обычного текста, который вернет ответ с параметром data
в качестве содержимого ответа.
Установка набора символов
По умолчанию предполагается, что классы рендеринга используют кодировку UTF-8
. Чтобы использовать другую кодировку, установите атрибут charset
для рендерера.
Обратите внимание, что если класс рендерера возвращает строку unicode, то содержимое ответа будет преобразовано в строку байт классом Response
, при этом атрибут charset
, установленный на рендерере, будет использоваться для определения кодировки.
Если рендерер возвращает строку байт, представляющую необработанное двоичное содержимое, вам следует установить значение charset равное None
, что обеспечит отсутствие в заголовке Content-Type
ответа значения charset
.
В некоторых случаях вы также можете установить атрибут render_style
на 'binary'
. Это также гарантирует, что Web-интерфейс API не будет пытаться отобразить двоичное содержимое в виде строки.
Расширенное использование рендеринга
Вы можете делать довольно гибкие вещи, используя рендереры DRF. Некоторые примеры...
Предоставление плоских или вложенных представлений из одной и той же конечной точки, в зависимости от запрашиваемого типа носителя.
Предоставлять как обычные веб-страницы HTML, так и ответы API на основе JSON с одной и той же конечной точки.
Указывать несколько типов представления HTML для использования клиентами API.
Недоопределять медиатип рендерера, например, используя
media_type = 'image/*'
, и использовать заголовокAccept
для изменения кодировки ответа.
Различное поведение в зависимости от типа носителя
В некоторых случаях вы можете захотеть, чтобы ваше представление использовало различные стили сериализации в зависимости от принятого типа носителя. Если вам нужно сделать это, вы можете обратиться к request.accepted_renderer
, чтобы определить согласованный рендерер, который будет использоваться для ответа.
Например:
Недоопределение типа носителя.
В некоторых случаях вы можете захотеть, чтобы рендерер обслуживал различные типы медиа. В этом случае вы можете не указывать типы медиа, на которые он должен реагировать, используя значение media_type
, такое как image/*
, или */*
.
Если вы недоопределили медиатип рендерера, вы должны убедиться, что указали медиатип явно, когда возвращаете ответ, используя атрибут content_type
. Например:
Проектирование типов носителей
Для целей многих Web API может быть достаточно простых ответов JSON
с гиперссылками на отношения. Если вы хотите полностью внедрить RESTful дизайн и HATEOAS, вам необходимо более детально продумать дизайн и использование типов медиа.
По словам Роя Филдинга, "REST API должен потратить почти все свои усилия по описанию на определение типа(ов) медиа, используемых для представления ресурсов и управления состоянием приложения, или на определение расширенных имен отношений и/или гипертекстовой разметки для существующих стандартных типов медиа".
Хорошими примерами пользовательских типов медиа являются использование GitHub пользовательского типа медиа application/vnd.github+json и одобренная IANA гипермедиа на основе JSON application/vnd.collection+json Майка Амундсена.
HTML представления ошибок
Обычно рендерер ведет себя одинаково независимо от того, имеет ли он дело с обычным ответом или с ответом, вызванным возникшим исключением, например, исключением Http404
или PermissionDenied
, или подклассом APIException
.
Если вы используете TemplateHTMLRenderer
или StaticHTMLRenderer
и при этом возникает исключение, поведение немного отличается и является зеркальным отражением Django's default handling of error views.
Исключения, возникающие и обрабатываемые средством рендеринга HTML, будут пытаться отобразить с помощью одного из следующих методов, в порядке старшинства.
Загрузите и отобразите шаблон с именем
{status_code}.html
.Загрузите и отобразите шаблон с именем
api_exception.html
.Вывести код статуса HTTP и текст, например, "404 Not Found".
Шаблоны будут отображаться с RequestContext
, который включает ключи status_code
и details
.
Примечание: Если DEBUG=True
, то вместо отображения кода статуса HTTP и текста будет отображаться стандартная страница ошибки трассировки Django.
Пакеты сторонних производителей
Также доступны следующие пакеты сторонних производителей.
YAML
REST framework YAML обеспечивает поддержку разбора и рендеринга YAML. Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.
Установка и настройка
Установите с помощью pip.
Измените настройки DRF.
XML
REST Framework XML предоставляет простой неформальный формат XML. Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.
Установка и настройка
Установите с помощью pip.
Измените настройки DRF.
JSONP
REST framework JSONP обеспечивает поддержку рендеринга JSONP. Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.
Предупреждение: Если вам требуются междоменные AJAX-запросы, вам следует использовать более современный подход CORS в качестве альтернативы JSONP
. Более подробную информацию смотрите в документации CORS.
Подход jsonp
по сути является хаком для браузера и подходит только для глобально читаемых конечных точек API, где запросы GET
являются неаутентифицированными и не требуют никаких разрешений пользователя.
Установка и настройка
Установите с помощью pip.
Измените настройки DRF.
MessagePack
MessagePack - это быстрый и эффективный формат двоичной сериализации. Juan Riaza поддерживает пакет djangorestframework-msgpack, который обеспечивает поддержку рендеринга и парсера MessagePack для DRF.
Microsoft Excel: XLSX (Двоичные конечные точки электронных таблиц)
XLSX - это самый популярный в мире формат двоичных электронных таблиц. Тим Аллен из The Wharton School поддерживает drf-excel, который отображает конечную точку в виде электронной таблицы XLSX с помощью OpenPyXL и позволяет клиенту загрузить ее. Электронные таблицы могут быть стилизованы для каждого вида.
Установка и настройка
Установите с помощью pip.
Измените настройки DRF.
Чтобы избежать потоковой передачи файла без имени (при этом браузер часто принимает по умолчанию имя файла "download" без расширения), нам необходимо использовать миксин для переопределения заголовка Content-Disposition
. Если имя файла не указано, то по умолчанию будет задано export.xlsx
. Например:
CSV
Значения, разделенные запятыми, - это формат табличных данных в виде обычного текста, который легко импортируется в приложения электронных таблиц. Mjumbe Poe поддерживает пакет djangorestframework-csv, который обеспечивает поддержку CSV-рендеринга для DRF.
UltraJSON
UltraJSON - это оптимизированный кодировщик JSON на языке C, который может значительно ускорить рендеринг JSON. Adam Mertz поддерживает drf_ujson2, форк ныне не поддерживаемого drf-ujson-renderer, который реализует рендеринг JSON с использованием пакета UJSON.
CamelCase JSON
djangorestframework-camel-case предоставляет рендереры и парсеры JSON в верблюжьем регистре для DRF. Это позволяет сериализаторам использовать имена полей в стиле Python с подчеркиванием, но отображать их в API как имена полей в верблюжьем регистре в стиле Javascript. Поддерживается Виталием Бабием.
Pandas (CSV, Excel, PNG)
Django REST Pandas предоставляет сериализатор и рендереры, которые поддерживают дополнительную обработку и вывод данных через Pandas DataFrame API. Django REST Pandas включает рендереры для файлов CSV в стиле Pandas, рабочих книг Excel (как .xls
, так и .xlsx
) и ряда других форматов. Он поддерживается S. Andrew Sheppard в рамках проекта wq Project.
LaTeX
Rest Framework Latex предоставляет рендерер, который выводит PDF-файлы с использованием Laulatex. Он поддерживается Pebble (S/F Software).
Last updated