呈现器-Django REST框架
渲染器
在将TemplatResponse实例返回给客户端之前,必须呈现它。呈现过程采用模板和上下文的中间表示,并将其转换为可以服务于客户端的最终字节流。
— Django文档
REST框架包括许多内置在Renderer类中的内容,这些类允许您返回各种媒体类型的响应。还支持定义您自己的自定义呈现器,这使您可以灵活地设计自己的媒体类型。
如何确定渲染器
视图的有效呈现器集总是定义为类的列表。当输入视图时,REST框架将对传入的请求执行内容协商,并确定满足请求的最合适的呈现器。
内容协商的基本过程包括检查请求的Accept
标头,以确定它在响应中所期望的媒体类型。可以选择,URL上的格式后缀可用于显式请求特定的表示形式。例如,URLhttp://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响应的视图,则可以考虑TemplatumHTMLRenderer
您的默认呈现程序,以便很好地处理较早的浏览器中断接受标头.
API参考
JSONRenderer
将请求数据呈现为JSON
,使用utf-8编码。
请注意,默认样式是包含Unicode字符,并使用没有不必要空格的紧凑样式呈现响应:
{"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
.格式: 'json'
.字符集: None
TemplatumHTMLRenderer
使用Django的标准模板呈现将数据呈现到HTML。与其他呈现器不同,数据传递给Response
不需要序列化。另外,与其他渲染器不同,您可能希望包括template_name
在创建Response
.
TemplatumHTMLRenderer将创建一个RequestContext
,使用response.data
并确定用于呈现上下文的模板名。
模板名称由(按优先顺序排列)确定:
- 明示
template_name
参数传递给响应。 - 明示
.template_name
属性设置在该类上。 - 调用的返回结果
view.get_template_names()
.
视图的示例,该视图使用TemplatumHTMLRenderer
:
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')
你可以用TemplatumHTMLRenderer
使用REST框架返回常规HTML页面,或者从单个端点返回HTML和API响应。
如果你在建立网站TemplatumHTMLRenderer
与其他呈现类一起,您应该考虑列出TemplatumHTMLRenderer
作为renderer_classes
列表,以便即使对于发送格式错误的浏览器,它也将被优先排序。ACCEPT:
标题。
见HTML&Forms主题页的进一步例子TemplatumHTMLRenderer
使用。
.Media_type: text/html
.格式: 'html'
.字符集: utf-8
另见:静态HTMLRenderer
静态HTMLRenderer
一个简单的呈现器,它只返回预渲染的HTML。与其他呈现器不同,传递给响应对象的数据应该是表示要返回的内容的字符串。
视图的示例,该视图使用静态HTMLRenderer
:
@api_view(['GET'])
@renderer_classes([StaticHTMLRenderer])
def simple_html_view(request):
data = '<html><body><h1>Hello, world</h1></body></html>'
return Response(data)
你可以用静态HTMLRenderer
使用REST框架返回常规HTML页面,或者从单个端点返回HTML和API响应。
.Media_type: text/html
.格式: 'html'
.字符集: utf-8
另见:TemplatumHTMLRenderer
BrowsableAPIRenderer
将数据呈现为可浏览API的HTML:
![](https://i-blog.csdnimg.cn/blog_migrate/26c834349e466f5104c543996e2b407d.png)
此呈现器将确定哪些其他呈现器将被赋予最高优先级,并使用它在HTML页面中显示API样式响应。
.Media_type: text/html
.格式: 'api'
.字符集: utf-8
.模板: 'rest_framework/api.html'
定制BrowsableAPIRenderer
默认情况下,响应内容将使用除BrowsableAPIRenderer
...如果您需要自定义此行为,例如使用HTML作为默认返回格式,但在可浏览API中使用JSON,则可以通过重写get_default_renderer()
方法。例如:
class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
def get_default_renderer(self, view):
return JSONRenderer()
管理员
为类似管理的显示将数据呈现到HTML中:
![](https://i-blog.csdnimg.cn/blog_migrate/a9844174cc026e226ffdf41d5d250fe3.png)
此呈现器适用于CRUD风格的WebAPI,该API还应该为管理数据提供一个用户友好的界面。
注意,对于其输入具有嵌套或列表序列化程序的视图将不能很好地处理管理员
,因为HTML表单无法正确地支持它们。
注*管理员
配置正确时,才能包含到详细信息页的链接。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
.格式: 'admin'
.字符集: utf-8
.模板: '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>
有关更多信息,请参见HTML&Forms文件。
.Media_type: text/html
.格式: 'form'
.字符集: utf-8
.模板: 'rest_framework/horizontal/form.html'
多伙伴渲染器
此呈现器用于呈现HTML多部分表单数据。它不适合作为响应呈现器。,而是用于创建测试请求,使用REST框架的测试客户端和测试请求工厂.
.Media_type: multipart/form-data; boundary=BoUnDaRyStRiNg
.格式: 'multipart'
.字符集: utf-8
自定义渲染器
若要实现自定义呈现程序,应重写BaseRenderer
,设置.Media_type
和.格式
属性,并实现.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
.
例
下面是一个示例纯文本呈现程序,它将返回带有data
参数作为响应的内容。
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)
注意,如果呈现程序类返回Unicode字符串,则响应内容将被Response
类的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框架的呈现器执行一些非常灵活的操作。一些例子..。
- 根据请求的媒体类型,从同一端点提供平面或嵌套表示。
- 提供来自相同端点的常规HTML网页和基于JSON的API响应。
- 为API客户端指定多种类型的HTML表示。
- 未指定渲染器的媒体类型,例如使用
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')
设计媒体类型
对于许多WebAPI来说,简单JSON
具有超链接关系的反应可能就足够了。如果你想完全接受RESTful的设计哈特乌斯您需要更详细地考虑媒体类型的设计和使用。
在……里面罗伊·菲尔丁的话“RESTAPI应该花费几乎所有的描述性努力来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有的标准媒体类型定义扩展的关系名称和/或启用超文本的标记。”
有关自定义媒体类型的良好示例,请参见GitHub对自定义的使用应用程序/vnd.gizub+json媒体类型,Mike Amundsen的IANA批准应用程序/vnd.Collection+json基于json的超媒体。
HTML错误视图
通常,呈现程序的行为都是相同的,不管它是处理常规响应,还是处理由引发的异常引起的响应,例如Http404
或PermissionDenied
异常,或APIException
.
如果您使用的是TemplatumHTMLRenderer
或者静态HTMLRenderer
如果引发异常,则行为略有不同,并且会出现镜像。Django对错误视图的默认处理.
HTML呈现程序引发和处理的异常将尝试按照优先级顺序使用下列方法之一呈现。
- 加载和呈现一个名为
{status_code}.html
. - 加载和呈现一个名为
api_exception.html
. - 呈现HTTP状态代码和文本,例如“404未找到”。
模板将使用RequestContext
,其中包括status_code
和details
钥匙。
注*如果DEBUG=True
,将显示Django的标准跟踪错误页面,而不是呈现HTTP状态代码和文本。
第三方包
下面的第三方包也是可用的。
YAML
REST框架YAML提供YAML解析和呈现支持。它以前直接包含在REST框架包中,现在被支持为第三方包。
安装与配置
使用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框架XML提供一种简单的非正式XML格式。它以前直接包含在REST框架包中,现在被支持为第三方包。
安装与配置
使用pip安装。
$ pip install djangorestframework-xml
修改REST框架设置。
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework_xml.parsers.XMLParser',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework_xml.renderers.XMLRenderer',
],
}
JSONP
REST框架JSONP提供JSONP呈现支持。它以前直接包含在REST框架包中,现在被支持为第三方包。
警告如果您需要跨域的ajax请求,通常应该使用更现代的方法CORS作为替代JSONP
...见CORS文档更多细节。
这个jsonp
方法本质上是一种浏览器攻击,并且是仅适用于全局可读的api端点。,在哪里GET
请求未经身份验证,不需要任何用户权限。
安装与配置
使用pip安装。
$ pip install djangorestframework-jsonp
修改REST框架设置。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework_jsonp.renderers.JSONPRenderer',
],
}
MessagePack
MessagePack是一种快速、高效的二进制序列化格式。胡安·里扎维护djangorestframework-msgpack包,它为REST框架提供MessagePack呈现器和解析器支持。
二进制电子表格端点
xlsx是世界上最流行的二进制电子表格格式。蒂姆·艾伦的沃顿商学院维护DRF-渲染器-xlsx,它使用OpenPyXL将端点呈现为xlsx电子表格,并允许客户端下载它。电子表格可以在每个视图的基础上进行样式设计。
安装与配置
使用pip安装。
$ pip install drf-renderer-xlsx
修改REST框架设置。
REST_FRAMEWORK = {
...
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
'drf_renderer_xlsx.renderers.XLSXRenderer',
],
}
为了避免没有文件名的文件流(浏览器通常默认为文件名“下载”,没有扩展名),我们需要使用混合文件来覆盖Content-Disposition
头球。如果没有提供文件名,则默认为export.xlsx
...例如:
from rest_framework.viewsets import ReadOnlyModelViewSet
from drf_renderer_xlsx.mixins import XLSXFileMixin
from drf_renderer_xlsx.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
逗号分隔的值是一种纯文本表格数据格式,可以很容易地导入到电子表格应用程序中.姆朱贝·坡维护djangorestframework-CSV为REST框架提供CSV渲染器支持的软件包。
UltraJSON
UltraJSON是一个优化的C JSON编码器,它可以提供更快的JSON呈现。雅各布·哈斯赫斯特维护DRF-ujson渲染器包,它使用UJSON包实现JSON呈现。
CamelCase JSON
djangorest框架-骆驼箱为REST框架提供CAMEL CASE JSON呈现器和解析器。这允许序列化程序使用Python风格的突出显示的字段名,但在API中公开为Javascript样式的CAMEL字段名。它是由维塔利.
熊猫(CSV,Excel,PNG)
Django休息Pandas提供支持其他数据处理和输出的序列化程序和呈现程序。熊猫DataFrameAPIDjango REST Pandas包括用于Pandas样式CSV文件、Excel工作簿的呈现器(两者均为.xls
和.xlsx
),以及一些其他格式...它是由安德鲁·谢泼德作为WQ项目.
乳胶
REST框架乳胶提供使用Laulatex输出PDF的呈现器。它是由鹅卵石(S/F软件).