Django REST Framework
  • Overview
    • Django REST framework
    • Быстрый старт
      • Сериализация
      • Запросы-ответы
      • Представления-классы
      • Аутентификация/права доступа
      • Отношения и связи
      • Наборы представлений и роутеры
    • Навигация по API:
      • Запросы
      • Ответы
      • Представления
      • Общие представления
      • Viewsets
      • Маршрутизаторы
      • Парсеры
      • Рендереры
      • Сериализаторы
      • Поля сериализатора
      • Отношения сериализаторов
      • Валидаторы
      • Аутентификация
      • Разрешения
      • Кэширование
      • Дросселирование
      • Фильтрация
      • Пагинация
      • Версионирование
      • Согласование контента
      • Метаданные
      • Schemas
      • Cуффиксы формата
      • Возвращение URL-адресов
      • Исключения
      • Коды состояния
      • Тестирование
      • Настройки
  • Статьи
    • Статьи
      • AJAX, CSRF & CORS
      • The Browsable API
      • Улучшения в браузере
      • Документирование вашего API
      • HTML и формы
      • Интернационализация
      • REST, гипермедиа и HATEOAS
      • Вложенные сериализаторы с возможностью записи
Powered by GitBook
On this page
  • Рендереры
  • Как определяется рендерер
  • Установка рендереров
  • Упорядочивание классов рендеринга
  • API Reference
  • JSONRenderer
  • TemplateHTMLRenderer
  • StaticHTMLRenderer
  • BrowsableAPIRenderer
  • AdminRenderer
  • HTMLFormRenderer
  • MultiPartRenderer
  • Пользовательские рендеры
  • Пример
  • Установка набора символов
  • Расширенное использование рендеринга
  • Различное поведение в зависимости от типа носителя
  • Недоопределение типа носителя.
  • Проектирование типов носителей
  • HTML представления ошибок
  • Пакеты сторонних производителей
  • YAML
  • XML
  • JSONP
  • MessagePack
  • Microsoft Excel: XLSX (Двоичные конечные точки электронных таблиц)
  • CSV
  • UltraJSON
  • CamelCase JSON
  • Pandas (CSV, Excel, PNG)
  • LaTeX

Was this helpful?

  1. Overview
  2. Навигация по API:

Рендереры

PreviousПарсерыNextСериализаторы

Last updated 1 year ago

Was this helpful?

Рендереры

Прежде чем экземпляр TemplateResponse будет возвращен клиенту, он должен быть отрендерен. Процесс рендеринга принимает промежуточное представление шаблона и контекста и превращает его в конечный поток байтов, который может быть передан клиенту.

DRF включает ряд встроенных классов Renderer, которые позволяют возвращать ответы с различными типами медиа. Также имеется поддержка определения собственных пользовательских рендереров, что дает вам гибкость в разработке собственных типов медиа.

Как определяется рендерер

Набор допустимых рендерингов для представления всегда определяется как список классов. При входе в представление DRF будет выполнять согласование содержимого входящего запроса и определять наиболее подходящий рендерер для удовлетворения запроса.

Основной процесс согласования содержимого включает в себя изучение заголовка Accept запроса, чтобы определить, какие типы медиа ожидаются в ответе. По желанию, суффиксы формата в URL могут быть использованы для явного запроса определенного представления. Например, URL http://example.com/api/users_count.json может быть конечной точкой, которая всегда возвращает данные в формате JSON.

Для получения дополнительной информации смотрите документацию по .

Установка рендереров

Набор рендеров по умолчанию можно задать глобально, используя параметр DEFAULT_RENDERER_CLASSES. Например, следующие настройки будут использовать JSON в качестве основного типа медиа, а также включать API самоописания.

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}

Вы также можете установить рендереры, используемые для отдельного представления или набора представлений, используя представления на основе класса APIView.

from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView

class UserCountView(APIView):
    """
    A view that returns the count of active users in JSON.
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        user_count = User.objects.filter(active=True).count()
        content = {'user_count': user_count}
        return Response(content)

Или, если вы используете декоратор @api_view с представлениями, основанными на функциях.

@api_view(['GET'])
@renderer_classes([JSONRenderer])
def user_count_view(request, format=None):
    """
    A view that returns the count of active users in JSON.
    """
    user_count = User.objects.filter(active=True).count()
    content = {'user_count': user_count}
    return Response(content)

Упорядочивание классов рендеринга

Важно при определении классов рендеринга для вашего API подумать о том, какой приоритет вы хотите присвоить каждому типу медиа. Если клиент недоопределяет представления, которые он может принимать, например, посылает заголовок Accept: */* заголовок, или вообще не включает заголовок Accept, то DRF выберет первый рендерер в списке для использования в ответе.

Например, если ваш API обслуживает JSON-ответы и HTML-просмотр, вы можете сделать JSONRenderer рендерером по умолчанию, чтобы отправлять JSON ответы клиентам, которые не указывают заголовок Accept.


API Reference

JSONRenderer

Переводит данные запроса в JSON, используя кодировку utf-8.

Обратите внимание, что стиль по умолчанию включает символы юникода и отображает ответ, используя компактный стиль без лишних пробелов:

{"unicode black star":"★","value":999}

Клиент может дополнительно включить параметр медиатипа 'indent', в этом случае возвращаемый JSON будет иметь отступ. Например, Accept: application/json; indent=4.

{
    "unicode black star": "★",
    "value": 999
}

Стиль кодировки 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 смог его отрендерить. Например:

response.data = {'results': response.data}

Имя шаблона определяется (в порядке предпочтения):

  1. Явный аргумент template_name, передаваемый в ответ.

  2. Явный атрибут .template_name, установленный для этого класса.

  3. Результат вызова view.get_template_names().

Пример представления, использующего TemplateHTMLRenderer:

class UserDetail(generics.RetrieveAPIView):
    """
    A view that returns a templated HTML representation of a given user.
    """
    queryset = User.objects.all()
    renderer_classes = [TemplateHTMLRenderer]

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return Response({'user': self.object}, template_name='user_detail.html')

Вы можете использовать TemplateHTMLRenderer либо для возврата обычных HTML-страниц с помощью DRF, либо для возврата HTML и API ответов с одной конечной точки.

Если вы создаете сайты, использующие TemplateHTMLRenderer наряду с другими классами рендереров, вам следует рассмотреть возможность включения TemplateHTMLRenderer в качестве первого класса в список renderer_classes, чтобы он был приоритетным даже для браузеров, которые посылают плохо сформированные заголовки ACCEPT:.

.media_type: text/html.

.format: 'html'.

.charset: utf-8

См. также: StaticHTMLRenderer

StaticHTMLRenderer

Простой рендерер, который просто возвращает предварительно отрендеренный HTML. В отличие от других рендереров, данные, передаваемые в объект ответа, должны быть строкой, представляющей возвращаемое содержимое.

Пример представления, использующего StaticHTMLRenderer:

@api_view(['GET'])
@renderer_classes([StaticHTMLRenderer])
def simple_html_view(request):
    data = '<html><body><h1>Hello, world</h1></body></html>'
    return Response(data)

Вы можете использовать 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(). Например:

class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
    def get_default_renderer(self, view):
        return JSONRenderer()

AdminRenderer

Рендерит данные в HTML для отображения в стиле администратора:

Этот рендерер подходит для веб-интерфейсов в стиле CRUD, которые также должны представлять удобный интерфейс для управления данными.

Обратите внимание, что представления, которые имеют вложенные или списковые сериализаторы для своего ввода, не будут хорошо работать с AdminRenderer, так как HTML-формы не могут должным образом поддерживать их.

Примечание: AdminRenderer способен включать ссылки на детальные страницы только в том случае, если в данных присутствует правильно настроенный атрибут URL_FIELD_NAME (по умолчанию url). Для HyperlinkedModelSerializer так и будет, но для классов ModelSerializer или простого Serializer вам нужно будет убедиться, что поле включено явно. Например, здесь мы используем метод модели get_absolute_url:

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source='get_absolute_url', read_only=True)

    class Meta:
        model = Account

.media_type: text/html.

.format: 'admin'.

.charset: utf-8

.template: 'rest_framework/admin.html'.

HTMLFormRenderer

Переводит данные, возвращаемые сериализатором, в форму HTML. Вывод этого рендерера не включает заключающие теги <form>, скрытый CSRF-вход или какие-либо кнопки отправки.

Этот рендерер не предназначен для прямого использования, но может быть использован в шаблонах путем передачи экземпляра сериализатора в тег шаблона render_form.


<div data-gb-custom-block data-tag="load"></div>

<form action="/submit-report/" method="post">
    

<div data-gb-custom-block data-tag="csrf_token"></div>

    

<div data-gb-custom-block data-tag="render_form"></div>
    <input type="submit" value="Save" />
</form>

.media_type: text/html.

.format: 'format'.

.charset: utf-8

.template: 'rest_framework/horizontal/form.html'.

MultiPartRenderer

.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

Данные запроса, заданные инстанцией Response().

accepted_media_type=None

Дополнительно. Если указано, то это принятый тип носителя, определенный на этапе согласования содержимого.

В зависимости от заголовка Accept: клиента, он может быть более конкретным, чем атрибут media_type рендерера, и может включать параметры типа медиа. Например, 'application/json; nested=true'.

renderer_context=None

Опционально. Если предоставляется, то это словарь контекстной информации, предоставляемой представлением.

По умолчанию сюда входят следующие ключи: view, request, response, args, kwargs.

Пример

Ниже приведен пример рендеринга обычного текста, который вернет ответ с параметром data в качестве содержимого ответа.

from django.utils.encoding import smart_str
from rest_framework import renderers


class PlainTextRenderer(renderers.BaseRenderer):
    media_type = 'text/plain'
    format = 'txt'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        return smart_str(data, encoding=self.charset)

Установка набора символов

По умолчанию предполагается, что классы рендеринга используют кодировку UTF-8. Чтобы использовать другую кодировку, установите атрибут charset для рендерера.

class PlainTextRenderer(renderers.BaseRenderer):
    media_type = 'text/plain'
    format = 'txt'
    charset = 'iso-8859-1'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        return data.encode(self.charset)

Обратите внимание, что если класс рендерера возвращает строку unicode, то содержимое ответа будет преобразовано в строку байт классом Response, при этом атрибут charset, установленный на рендерере, будет использоваться для определения кодировки.

Если рендерер возвращает строку байт, представляющую необработанное двоичное содержимое, вам следует установить значение charset равное None, что обеспечит отсутствие в заголовке Content-Type ответа значения charset.

В некоторых случаях вы также можете установить атрибут render_style на 'binary'. Это также гарантирует, что Web-интерфейс API не будет пытаться отобразить двоичное содержимое в виде строки.

class JPEGRenderer(renderers.BaseRenderer):
    media_type = 'image/jpeg'
    format = 'jpg'
    charset = None
    render_style = 'binary'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        return data

Расширенное использование рендеринга

Вы можете делать довольно гибкие вещи, используя рендереры DRF. Некоторые примеры...

  • Предоставление плоских или вложенных представлений из одной и той же конечной точки, в зависимости от запрашиваемого типа носителя.

  • Предоставлять как обычные веб-страницы HTML, так и ответы API на основе JSON с одной и той же конечной точки.

  • Указывать несколько типов представления HTML для использования клиентами API.

  • Недоопределять медиатип рендерера, например, используя media_type = 'image/*', и использовать заголовок Accept для изменения кодировки ответа.

Различное поведение в зависимости от типа носителя

В некоторых случаях вы можете захотеть, чтобы ваше представление использовало различные стили сериализации в зависимости от принятого типа носителя. Если вам нужно сделать это, вы можете обратиться к request.accepted_renderer, чтобы определить согласованный рендерер, который будет использоваться для ответа.

Например:

@api_view(['GET'])
@renderer_classes([TemplateHTMLRenderer, JSONRenderer])
def list_users(request):
    """
    A view that can return JSON or HTML representations
    of the users in the system.
    """
    queryset = Users.objects.filter(active=True)

    if request.accepted_renderer.format == 'html':
        # TemplateHTMLRenderer takes a context dict,
        # and additionally requires a 'template_name'.
        # It does not require serialization.
        data = {'users': queryset}
        return Response(data, template_name='list_users.html')

    # JSONRenderer requires serialized data as normal.
    serializer = UserSerializer(instance=queryset)
    data = serializer.data
    return Response(data)

Недоопределение типа носителя.

В некоторых случаях вы можете захотеть, чтобы рендерер обслуживал различные типы медиа. В этом случае вы можете не указывать типы медиа, на которые он должен реагировать, используя значение media_type, такое как image/*, или */*.

Если вы недоопределили медиатип рендерера, вы должны убедиться, что указали медиатип явно, когда возвращаете ответ, используя атрибут content_type. Например:

return Response(data, content_type='image/png')

Проектирование типов носителей

HTML представления ошибок

Обычно рендерер ведет себя одинаково независимо от того, имеет ли он дело с обычным ответом или с ответом, вызванным возникшим исключением, например, исключением Http404 или PermissionDenied, или подклассом APIException.

Исключения, возникающие и обрабатываемые средством рендеринга HTML, будут пытаться отобразить с помощью одного из следующих методов, в порядке старшинства.

  • Загрузите и отобразите шаблон с именем {status_code}.html.

  • Загрузите и отобразите шаблон с именем api_exception.html.

  • Вывести код статуса HTTP и текст, например, "404 Not Found".

Шаблоны будут отображаться с RequestContext, который включает ключи status_code и details.

Примечание: Если DEBUG=True, то вместо отображения кода статуса HTTP и текста будет отображаться стандартная страница ошибки трассировки Django.


Пакеты сторонних производителей

Также доступны следующие пакеты сторонних производителей.

YAML

Установка и настройка

Установите с помощью pip.

$ pip install djangorestframework-yaml

Измените настройки DRF.

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_yaml.parsers.YAMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_yaml.renderers.YAMLRenderer',
    ],
}

XML

Установка и настройка

Установите с помощью pip.

$ pip install djangorestframework-xml

Измените настройки DRF.

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_xml.parsers.XMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_xml.renderers.XMLRenderer',
    ],
}

JSONP



Установка и настройка

Установите с помощью pip.

$ pip install djangorestframework-jsonp

Измените настройки DRF.

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_jsonp.renderers.JSONPRenderer',
    ],
}

MessagePack

Microsoft Excel: XLSX (Двоичные конечные точки электронных таблиц)

Установка и настройка

Установите с помощью pip.

$ pip install drf-excel

Измените настройки DRF.

REST_FRAMEWORK = {
    ...

    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
        'drf_excel.renderers.XLSXRenderer',
    ],
}

Чтобы избежать потоковой передачи файла без имени (при этом браузер часто принимает по умолчанию имя файла "download" без расширения), нам необходимо использовать миксин для переопределения заголовка Content-Disposition. Если имя файла не указано, то по умолчанию будет задано export.xlsx. Например:

from rest_framework.viewsets import ReadOnlyModelViewSet
from drf_excel.mixins import XLSXFileMixin
from drf_excel.renderers import XLSXRenderer

from .models import MyExampleModel
from .serializers import MyExampleSerializer

class MyExampleViewSet(XLSXFileMixin, ReadOnlyModelViewSet):
    queryset = MyExampleModel.objects.all()
    serializer_class = MyExampleSerializer
    renderer_classes = [XLSXRenderer]
    filename = 'my_export.xlsx'

CSV

UltraJSON

CamelCase JSON

Pandas (CSV, Excel, PNG)

LaTeX

Если ваш API включает представления, которые могут обслуживать как обычные веб-страницы, так и ответы API в зависимости от запроса, то вы можете сделать TemplateHTMLRenderer рендерером по умолчанию, чтобы хорошо работать со старыми браузерами, которые отправляют .

Дополнительные примеры использования TemplateHTMLRenderer смотрите в .

The BrowsableAPIRenderer
Вид AdminRender

Для получения дополнительной информации смотрите документацию .

Этот рендерер используется для рендеринга данных многочастной формы HTML. Он не подходит для рендеринга ответов, а используется для создания тестовых запросов, используя DRF.

Для целей многих Web API может быть достаточно простых ответов JSON с гиперссылками на отношения. Если вы хотите полностью внедрить RESTful дизайн и , вам необходимо более детально продумать дизайн и использование типов медиа.

По словам , "REST API должен потратить почти все свои усилия по описанию на определение типа(ов) медиа, используемых для представления ресурсов и управления состоянием приложения, или на определение расширенных имен отношений и/или гипертекстовой разметки для существующих стандартных типов медиа".

Хорошими примерами пользовательских типов медиа являются использование GitHub пользовательского типа медиа и одобренная IANA гипермедиа на основе JSON Майка Амундсена.

Если вы используете TemplateHTMLRenderer или StaticHTMLRenderer и при этом возникает исключение, поведение немного отличается и является зеркальным отражением .

обеспечивает поддержку разбора и рендеринга . Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.

предоставляет простой неформальный формат XML. Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.

обеспечивает поддержку рендеринга JSONP. Ранее он был включен непосредственно в пакет DRF, но теперь поддерживается как сторонний пакет.

Предупреждение: Если вам требуются междоменные AJAX-запросы, вам следует использовать более современный подход в качестве альтернативы JSONP. Более подробную информацию смотрите в документации .

Подход jsonp по сути является хаком для браузера и подходит , где запросы GET являются неаутентифицированными и не требуют никаких разрешений пользователя.

- это быстрый и эффективный формат двоичной сериализации. поддерживает пакет , который обеспечивает поддержку рендеринга и парсера MessagePack для DRF.

XLSX - это самый популярный в мире формат двоичных электронных таблиц. из поддерживает , который отображает конечную точку в виде электронной таблицы XLSX с помощью OpenPyXL и позволяет клиенту загрузить ее. Электронные таблицы могут быть стилизованы для каждого вида.

Значения, разделенные запятыми, - это формат табличных данных в виде обычного текста, который легко импортируется в приложения электронных таблиц. поддерживает пакет , который обеспечивает поддержку CSV-рендеринга для DRF.

- это оптимизированный кодировщик JSON на языке C, который может значительно ускорить рендеринг JSON. поддерживает , форк ныне не поддерживаемого , который реализует рендеринг JSON с использованием пакета UJSON.

предоставляет рендереры и парсеры JSON в верблюжьем регистре для DRF. Это позволяет сериализаторам использовать имена полей в стиле Python с подчеркиванием, но отображать их в API как имена полей в верблюжьем регистре в стиле Javascript. Поддерживается .

предоставляет сериализатор и рендереры, которые поддерживают дополнительную обработку и вывод данных через DataFrame API. Django REST Pandas включает рендереры для файлов CSV в стиле Pandas, рабочих книг Excel (как .xls, так и .xlsx) и ряда . Он поддерживается в рамках проекта .

предоставляет рендерер, который выводит PDF-файлы с использованием Laulatex. Он поддерживается .

Django documentation
согласованию контента
broken accept headers
HTML & Forms Topic Page
HTML & Forms
тестовый клиент и фабрику тестовых запросов
HATEOAS
Роя Филдинга
application/vnd.github+json
application/vnd.collection+json
Django's default handling of error views
REST framework YAML
YAML
REST Framework XML
REST framework JSONP
CORS
CORS
только для глобально читаемых конечных точек API
MessagePack
Juan Riaza
djangorestframework-msgpack
Тим Аллен
The Wharton School
drf-excel
Mjumbe Poe
djangorestframework-csv
UltraJSON
Adam Mertz
drf_ujson2
drf-ujson-renderer
djangorestframework-camel-case
Виталием Бабием
Django REST Pandas
Pandas
других форматов
S. Andrew Sheppard
wq Project
Rest Framework Latex
Pebble (S/F Software)