美文网首页
Django REST framework(四): DRF的渲

Django REST framework(四): DRF的渲

作者: 是立品啊 | 来源:发表于2020-07-13 08:19 被阅读0次

思考一下:为什么前端的形态不一致,请求drf接口返回的数据形式不一致?

定义

所谓的渲染器(Renderer),其实就是将服务器生成的数据的格式转换为HTTP请求的格式。
REST框架包含许多内置的Renderer类,可以返回各种媒体类型的响应。还支持定义自定义渲染
器,灵活地设计自己的媒体类型。

渲染模块的源码入口:APIView类的dispatch方法中

self.response = self.finalize_response(request, response, *args, **kwargs)
  • 查看:finalize_response(request, response, *args, **kwargs)
def finalize_response(self, request, response, *args, **kwargs):
    """
    Returns the final response object.
    """
    # Make the error obvious if a proper response is not returned
    assert isinstance(response, HttpResponseBase), (
        'Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` '
        'to be returned from the view, but received a `%s`'
        % type(response)
    )

    if isinstance(response, Response):
        if not getattr(request, 'accepted_renderer', None):
            neg = self.perform_content_negotiation(request, force=True)
            request.accepted_renderer, request.accepted_media_type = neg

        response.accepted_renderer = request.accepted_renderer
        response.accepted_media_type = request.accepted_media_type
        response.renderer_context = self.get_renderer_context()

    # Add new vary headers to the response instead of overwriting.
    vary_headers = self.headers.pop('Vary', None)
    if vary_headers is not None:
        patch_vary_headers(response, cc_delim_re.split(vary_headers))

    for key, value in self.headers.items():
        response[key] = value

    return response
  • 拿到运行解析类的对象们:self.perform_content_negotiation(request, force=True)
def perform_content_negotiation(self, request, force=False):
    """
    Determine which renderer and media type to use render the response.
    """
    renderers = self.get_renderers()
    conneg = self.get_content_negotiator()

    try:
        return conneg.select_renderer(request, renderers, self.format_kwarg)
    except Exception:
        if force:
            return (renderers[0], renderers[0].media_type)
        raise
  • 获取解析类对象:renderers = self.get_renderers()
def get_renderers(self):
    """
    Instantiates and returns the list of renderers that this view can use.
    """
    return [renderer() for renderer in self.renderer_classes]
  • self.renderer_classes获取renderer_classes,然后从api_settings中获取渲染模块的配置,获取的顺序如下,所有优先级也是从上至下
    1.自己视图类的类属性(局部配置)

    2.APIView类的类属性设置

    3.自己配置文件的DEFAULT_RENDERER_CLASSES(全局配置)

    4.DRF配置文件的DEFAULT_RENDERER_CLASSES

自定义配置渲染模块

全局配置

setting.py文件下加入以下配置:所有视图类统一处理,以下设置也是默认设置

REST_FRAMEWORK = {
    # drf提供的渲染类
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',       #只显示出json数据
        'rest_framework.renderers.BrowsableAPIRenderer',    #渲染出页面,注意是BrowsableAPIRenderer
    ],
}

局部配置

  • 某一个或一些实体类单独处理,在views.py视图类中提供对应的类属性
from rest_framework.renderers import JSONRenderer
class Test2(APIView):
    # 局部配置
    renderer_classes = [JSONRenderer]
    def get(self, request, *args, **kwargs):
        return Response('this get request is ok')

    def post(self, request, *args, **kwargs):
        return Response('this post request is ok')

排序渲染器类的顺序

在为API指定渲染器类时,要考虑清楚为每种媒体类型分配什么样的优先级,这一点很重要。如
果客户端未明确指定它可以接受的内容类型,例如发送 Accept: */* 属性值,或者根本没有
Accept 属性值,那么REST框架将选择settings列表中的第一个渲染器用于渲染响应内容。
如果你的API包含可根据请求的不同,同时提供常规网页和API响应的视图,请使用
TemplateHTMLRenderer 作为默认渲染器。

相关文章

网友评论

      本文标题:Django REST framework(四): DRF的渲

      本文链接:https://www.haomeiwen.com/subject/qccocktx.html