Руководство по API платформы Django REST (1): запросы
Руководство по API платформы Django REST (2): ответы
Руководство по API платформы Django REST (3): представления
Руководство по API платформы Django REST (4): общие представления
Руководство по API платформы Django REST (5): наборы представлений
Руководство по API платформы Django REST (6): Маршрутизация
Руководство по API платформы Django REST (7): анализ
Руководство по API Django REST framework (8): рендеринг
оказывать
Платформа REST включает в себя ряд встроенных классов рендеринга, которые позволяют вам возвращать ответы с различными типами мультимедиа. Также поддерживает пользовательские рендереры.
Как определить, какой рендерер использовать
Набор визуализаторов представления всегда определяется как список классов. Когда представление вызывается, платформа REST анализирует содержимое запроса и определяет наиболее подходящий модуль визуализации для удовлетворения запроса. Основной процесс контент-анализа состоит в изучении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
заголовок, платформа REST выберет первый модуль визуализации в списке, который будет использоваться для ответа.
Например, если ваш API предоставляет ответы JSON и HTML API с возможностью просмотра, вам может потребоватьсяJSONRenderer
в качестве средства визуализации по умолчанию, чтобыJSON
Ответ отправлен не указанномуAccept
заголовок клиента.
Если ваш API содержит представления, которые обрабатывают как обычные веб-страницы, так и ответы API по запросу, вы можете рассмотреть возможность добавленияTemplateHTMLRenderer
Установите в качестве средства визуализации по умолчанию, чтобы хорошо работать со старыми браузерами, отправляющими неработающие заголовки принятия.
Справочник по API
JSONRenderer
Отобразить данные запроса в виде кодировки utf-8JSON
.
Обратите внимание, что стиль по умолчанию включает символы Юникода и отображает ответ в компактном стиле (без лишних пробелов):
{"unicode black star":"★","value":999}
Клиенты могут также включать параметр типа мультимедиа "indent", и в этом случае возвращаемыйJSON
будет с отступом.
Например:Accept: application/json; indent=4
.
{
"unicode black star": "★",
"value": 999
}
использоватьUNICODE_JSON
иCOMPACT_JSON
Установите ключ, чтобы изменить стиль кодирования JSON по умолчанию.
.media_type:application/json
.format:'.json'
.charset:None
TemplateHTMLRenderer
Визуализация данных в формате HTML с использованием стандартных шаблонов Django. В отличие от других рендереров, передаетсяResponse
Данные не нужно сериализовать. Кроме того, создайтеResponse
может потребоваться включитьtemplate_name
параметр.
TemplateHTMLRenderer создастRequestContext
,использоватьresponse.data
В качестве словаря контекста и определяет имя шаблона, используемого для отображения контекста.
Имена шаблонов определяются (в порядке старшинства) по:
- Явно передается в ответ
template_name
параметр. - Установить явное значение для этого класса
.template_name
Атрибуты. - перечислить
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
чтобы платформа REST возвращала обычные HTML-страницы или возвращала ответы HTML и API из одной конечной точки.
Если вы строите с помощьюTemplateHTMLRenderer
и другие сайты, похожие на рендереры, вам следует подумать о добавленииTemplateHTMLRenderer
указан какrenderer_classes
Первый класс в списке, так что даже для отправки некорректныхACCEPT:
заголовок, также отдаст ему приоритет.
.media_type:text/html
.format:'.html'
.charset:utf-8
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
чтобы платформа REST возвращала обычные HTML-страницы или возвращала ответы HTML и API из одной конечной точки.
.media_type:text/html
.format:'.html'
.charset:utf-8
BrowsableAPIRenderer
Отображение данных в доступном для просмотра HTML API:
Этот модуль визуализации будет определять, какой другой модуль визуализации имеет наивысший приоритет, и использовать этот модуль визуализации для отображения ответа в стиле API на HTML-странице.
.media_type:text/html
.format:'.api'
.charset:utf-8
.template:'rest_framework/api.html'
Пользовательский BrowsableAPIRenderer
По умолчанию, кромеBrowsableAPIRenderer
В противном случае содержимое ответа будет отображаться с использованием средства визуализации с наивысшим приоритетом. Если вам нужно настроить это поведение, например, чтобы использовать HTML в качестве формата возврата по умолчанию, но использовать JSON в доступном для просмотра API, вы можете сделать это, переопределивget_default_renderer()
метод достижения.
Например:
class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
def get_default_renderer(self, view):
return JSONRenderer()
AdminRenderer
Отобразите данные в виде HTML, чтобы отобразить содержимое, похожее на администратора:
Этот рендерер работает с веб-API в стиле CRUD, который также должен предоставлять удобный интерфейс для управления данными.
Пожалуйста, обрати внимание,AdminRenderer
Не работает для представлений, которые вкладывают или перечисляют сериализованные входные данные, поскольку HTML-формы не поддерживают их должным образом.
Уведомление: при наличии правильно настроенногоURL_FIELD_NAME
(по умолчаниюurl
) имущество,AdminRenderer
Может содержать только ссылки на подробные страницы. заHyperlinkedModelSerializer
, это так, но дляModelSerializer
класс или обычныйSerializer
class, вы должны убедиться, что это поле включено явно. Например, здесь мы используем модель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
Теги шаблона для использования в шаблонах.
{% load rest_framework %}
<form action="/submit-report/" method="post">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save" />
</form>
.media_type:text/html
.format:'.form'
.charset:utf-8
.template:'rest_framework/horizontal/form.html'
MultiPartRenderer
Этот модуль визуализации используется для визуализации данных составной формы HTML. Он подходит не для рендеринга ответов, а для создания тестовых запросов с использованием тестового клиента REST framework и фабрики тестовых запросов.
.media_type:multipart/form-data; boundary=BoUnDaRyStRiNg
.format:'.multipart'
.charset:utf-8
пользовательский рендерер
Чтобы реализовать собственный рендерер, вы должны наследоватьBaseRenderer
,настраивать.media_type
и.format
свойства и реализовать.render(self, data, media_type=None, renderer_context=None)
метод.
Метод должен возвращать строку, которая будет использоваться в качестве тела ответа HTTP.
Перейти к.render()
Параметры метода:
data
запросить данные, поResponse()
Устанавливается при создании экземпляра.
media_type=None
по желанию. Если указано, это допустимый тип мультимедиа, определенный на этапе согласования контента.
зависимый от клиентаAccept:
заголовок, который можно сравнить с рендереромmedia_type
Свойства являются более конкретными и могут содержать параметры типа носителя. Например"application/json; nested=true"
.
renderer_context=None
по желанию. Если предоставлено, это словарь контекстной информации, предоставляемой представлением.
По умолчанию это будет включать следующие ключи:view
, request
, response
, args
, kwargs
.
взять каштан
Ниже приведен пример средства визуализации простого текста, который возвращает ответ с параметрами данных в качестве содержимого ответа.
from django.utils.encoding import smart_unicode
from rest_framework import renderers
class PlainTextRenderer(renderers.BaseRenderer):
media_type = 'text/plain'
format = 'txt'
def render(self, data, media_type=None, renderer_context=None):
return data.encode(self.charset)
установить кодировку
По умолчанию предполагается, что классы средства визуализации используют кодировку UTF-8. Чтобы использовать другую кодировку, установите на рендеререcharset
Атрибуты.
class PlainTextRenderer(renderers.BaseRenderer):
media_type = 'text/plain'
format = 'txt'
charset = 'iso-8859-1'
def render(self, data, media_type=None, renderer_context=None):
return data.encode(self.charset)
Обратите внимание, что если класс рендерера возвращает строку в Юникоде, содержимое ответа будетResponse
класс приведен к байтовой строке, пожалуйста, установите на рендеререcharset
Свойства используются для определения кодировки.
Если средство визуализации возвращает строку, представляющую необработанное двоичное содержимое, оно должноcharset
установлено значениеNone
, что гарантирует, что ответ будетContent-Type
заголовок не будет установленcharset
ценность.
В некоторых случаях вы также можетеrender_style
свойство установлено на'binary'
. Это также гарантирует, что доступный для просмотра API не будет пытаться отображать двоичное содержимое в виде строк.
class JPEGRenderer(renderers.BaseRenderer):
media_type = 'image/jpeg'
format = 'jpg'
charset = None
render_style = 'binary'
def render(self, data, media_type=None, renderer_context=None):
return data
Расширенное использование рендереров
Вы можете использовать рендереры REST framework, чтобы делать очень гибкие вещи. Например...
- Предоставляет плоское или вложенное представление из той же конечной точки, в зависимости от запрошенного типа мультимедиа.
- Обрабатывайте как обычные веб-страницы 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')
Создайте свой медиа-тип
Для многих целей веб-API может быть достаточно простого ответа JSON с гиперссылками. Если вы хотите полностью использовать дизайн RESTful и HATEOAS, вам необходимо более подробно рассмотреть дизайн и использование типов носителей.
Просмотр ошибок HTML
Как правило, независимо от того, имеете ли вы дело с обычным ответом или ответом, выдающим исключение (например,Http404
илиPermissionDenied
исключение) илиAPIException
Ответ, вызванный подклассом средства визуализации, будет иметь такое же поведение.
если вы используетеTemplateHTMLRenderer
илиStaticHTMLRenderer
, и выдает исключение, поведение немного отличается, отражая стандартную обработку представлений ошибок в Django.
Исключения, созданные и обработанные средством визуализации HTML, попытаются выполнить визуализацию с использованием одного из следующих методов (в порядке предпочтения).
- Загрузите и визуализируйте шаблон
{status_code}.html
. - Загрузите и визуализируйте шаблон
api_exception.html
. - Отображает коды состояния HTTP и текст, например «404 Not Found».
шаблон будет использоватьRequestContext
для рендеринга, который содержитstatus_code
иdetails
ключ.
Примечание: если
DEBUG = True
, вместо кода состояния HTTP и текста отображается стандартная страница трассировки ошибок Django.