django-rest-framework:使用相同的ModelViewSet渲染HTML和JSON

时间:2017-01-13 13:12:01

标签: python django django-rest-framework

我正在使用Django==1.10.5djangorestframework==3.5.3

我有一些ModelViewSet正确处理JSON API请求。现在,我想使用TemplateRenderer将HTML呈现添加到相同的ModelViewSet。我从list端点开始,创建了一个列出可用对象的简单模板。我实现了get_template_names以返回我创建的模板。

当列出 no 对象时,通过浏览器访问该端点工作正常,因此与API一起设置HTML渲染器的所有内容似乎都有效。但是,当tere是返回相同的对象时端点失败,出现以下错误:

ValueError: dictionary update sequence element #0 has length XX; 2 is required

其中XX是对象拥有的属性数。

This文档部分建议在返回HTML Response对象时,视图函数的行为应略有不同,但我认为这是在必要时由DRF的内置视图完成的,所以我不要&# 39;不要认为这是个问题。

This stackoverflow Q / A看起来也很相关,但我不太确定它是解决我问题的正确方法。

如何使ModelViewSet能够同时使用HTML和JSON渲染器? 谢谢!

1 个答案:

答案 0 :(得分:1)

DRF在their documentation中对此进行了简要说明。

我想你会做这样的事情...

在客户端,告诉端点您想要什么类型的响应:

fetch(yourAPIUrl, {
    headers: {
      'Accept': 'application/json'
      // or 'Accept': 'text/html'
    }
  })

您认为,只需检查并采取相应措施即可:

class FlexibleAPIView(APIView):
    """
    API view that can render either JSON or HTML.
    """
    renderer_classes = [TemplateHTMLRenderer, JSONRenderer]

    def get(self, request, *args, **kwargs):
        queryset = Things.objects.all()

        # If client wants HTML, give them HTML.
        if request.accepted_renderer.format == 'html':
            return Response({'things': queryset}, template_name='example.html')

        # Otherwise, the client likely wants JSON so serialize the data.
        serializer = ThingSerializer(instance=queryset)
        data = serializer.data
        return Response(data)