rest framework renderers
阅读原文时间:2023年07月09日阅读:2

渲染器

前TemplateResponse实例可以被返回给客户端,它必须被渲染。渲染过程需要模板和上下文的中间表示,并把它变成能够提供给客户端的最后一个字节流。

- Django文档

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来想想你要分配给各媒体类型是什么时,优先考虑这一点很重要。如果客户端underspecifies它可以接受的陈述,如发送一个Accept: */*报头,或者不包括Accept在所有的标题,然后REST框架将在列表中选择要使用的响应第一渲染器。

例如,如果你的API提供JSON响应和HTML浏览的API,你可能想使JSONRenderer你的默认渲染,以发送JSON回应那些没有指定的客户端Accept头。

如果您的API包含的视图可以起到既普通网页和API响应根据请求,那么你可能会考虑TemplateHTMLRenderer您的默认渲染器,以便与旧版本浏览器送发挥很好破碎接受头


API参考

呈现请求数据成JSON,使用UTF-8编码。

需要注意的是默认的风格是包括Unicode字符,并使用简洁的风格,没有多余的空格呈现响应:

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

客户机可以另外包括'indent'媒体类型参数,在这种情况下,返回JSON将被缩进。例如Accept: application/json; indent=4

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

默认JSON编码风格,可以使用被改变UNICODE_JSONCOMPACT_JSON设置键。

.media_typeapplication/json

.format'json'

.charsetNone

数据呈现到HTML,使用Django的标准模板渲染。不像其他的渲染器,将数据传递给Response不需要不被序列化。此外,与其他渲染器,你可能要包括template_name创建时的说法Response

该TemplateHTMLRenderer将创建一个RequestContext使用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任一返回使用REST框架普通的HTML页面,或从一个端点返回HTML和API响应。

如果你正在构建网站,使用TemplateHTMLRenderer其他渲染器类,您应该考虑上市TemplateHTMLRenderer作为第一类renderer_classes列表,因此,这将是第一优先即使对于发送格式不好的浏览器ACCEPT:标题。

查看HTML和表单主题页为进一步的例子TemplateHTMLRenderer使用。

.media_typetext/html

.format'html'

.charsetutf-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_typetext/html

.format'html'

.charsetutf-8

也可以看看: TemplateHTMLRenderer

数据呈现到HTML的可浏览API:

该渲染器将确定哪些其他渲染器将被赋予最高的优先级,并用它来显示HTML页面中的API风格的响应。

.media_typetext/html

.format'api'

.charsetutf-8

.template'rest_framework/api.html'

定制BrowsableAPIRenderer

默认情况下,响应内容将具有最高优先级的渲染器除了呈现BrowsableAPIRenderer。如果你需要定制这一行为,例如使用HTML作为默认返回格式,但可浏览API中使用JSON,你可以通过重写这样做的get_default_renderer()方法。例如:

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

呈现数据转换成HTML为管理式显示:

该渲染器适用于CRUD样式的Web的API,也应该提供用户友好的界面来管理数据。

请注意,嵌套观点或列表串行征求他们的意见不会与很好地工作AdminRenderer,因为HTML表单无法正确地支持他们。

:该AdminRenderer是唯一能够提供链接到详细信息页面时,正确配置URL_FIELD_NAMEurl默认)属性出现在数据中。对于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_typetext/html

.format'admin'

.charsetutf-8

.template'rest_framework/admin.html'

通过渲染串行返回到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和表单文档。

.media_typetext/html

.format'form'

.charsetutf-8

.template'rest_framework/horizontal/form.html'

该渲染器用于渲染HTML多形式的数据。 它不适合作为响应呈现器,而是被用于创建测试请求,使用REST框架的测试客户端和测试请求工厂

.media_typemultipart/form-data; boundary=BoUnDaRyStRiNg

.format'multipart'

.charsetutf-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

可选的。如果提供的话,这是由视图提供的上下文信息的字典。

默认情况下,这将包括以下键:viewrequestresponseargskwargs

以下是一个例子明文渲染器将返回与一个响应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响应。
  • 指定多个类型的HTML表示对API客户端使用。
  • Underspecify渲染器的媒体类型,如使用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)

在某些情况下,你可能需要一个渲染器提供一系列的媒体类型。在这种情况下,你可以underspecify媒体类型应该通过使用响应,media_type价值等image/*,或*/*

如果您underspecify渲染器的媒体类型,你应该确保指定当您返回响应媒体明确类型,使用content_type属性。例如:

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

对于许多Web的API的目的,简单的JSON使用超级链接关系的反应就足够了。如果你想完全接受REST风格的设计和HATEOAS你需要考虑你的媒体类型的设计和使用的更多细节。

罗伊菲尔丁的话说,“一个REST API应该花费几乎所有的其描述努力在确定用于表示资源和推动应用程序状态的媒体类型(S),或在定义扩展的关系名称和/或支持超文本mark-弥补现有标准的媒体类型。“

对于自定义的媒体类型的很好的例子,看到GitHub的使用自定义的应用程序/ vnd.github + json的媒体类型,和迈克阿蒙森的IANA批准申请/ vnd.collection + JSON基于JSON的超媒体。

通常,渲染器将具有相同的行为,无论它是否具有正规的反应,或引起异常的响应处理的提高,如的Http404PermissionDenied异常,或者一个子类APIException

如果您使用的是的TemplateHTMLRendererStaticHTMLRenderer与抛出一个异常,行为稍有不同,和镜子Django的错误观点默认处理

通过HTML渲染提高,处理的异常将尝试使用以下方法之一,通过优先次序来呈现。

  • 加载和渲染一个命名模板{status_code}.html
  • 加载和渲染一个命名模板api_exception.html
  • 渲染的HTTP状态代码和文字,例如“404未找到”。

模板将与渲染RequestContext其中包括status_codedetails钥匙。

注意:如果DEBUG=True,Django的标准回溯错误页面将显示,而不是渲染的HTTP状态代码和文本。


第三方软件包

下面的第三方软件包也可提供。

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',
    ],
}

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',
    ],
}

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是一种快速,高效的二进制序列化格式。 胡安里亚萨保持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',
    ],
}

为了避免文件流没有文件名(该浏览器将通常默认的文件名“下载”,不带扩展名),我们需要使用一个mixin覆盖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'

逗号分隔值是一个纯文本的表格数据的格式,可以很容易地导入到电子表格应用程序。Mjumbe坡维持djangorestframework-CSV包,它提供了一种用于REST框架CSV渲染器的支持。

UltraJSON是一个优化的C JSON编码器,其可以更快地显著给JSON渲染。雅各Haslehurst保持DRF-ujson,渲染它实现了JSON渲染使用UJSON包包。

djangorestframework-骆驼情况下提供骆驼情况下JSON渲染器和解析器REST框架。这允许串行器使用Python风格的下划线字段名,但API,如JavaScript式驼峰字段名中暴露出来。这是维护维塔利Babiy

Django的REST大熊猫提供串行器以及支持额外的数据处理和输出经由渲染熊猫数据帧API。Django的REST熊猫包括熊猫式的CSV文件渲染器,Excel工作簿(包括.xls.xlsx),以及一些其他格式。这是维护S.安德鲁·谢泼德作为的一部分WQ项目

其余框架胶乳提供了使用Laulatex输出的PDF渲染器。它由保持卵石(S / F软件)

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章