drf框架中的渲染组件

02-02 渲染组件

1.渲染组件的使用

在视图类中通过renderer_classes类属性对该视图的数据响应渲染做配置:

# 局部使用: views.py中
from rest_framework.renderers import JSONRenderer, BrowSableAPIRenderer

class BookAPIView(APIView):
    """
    JSONRenderer: JSON格式渲染
    BrowSAbleAPIRenderer: 浏览器页面渲染
    """
    renderer_classes = [JSONRenderer, BrowSableAPIRenderer]
    ...
    def get(self, request, *args, **kwargs): pass

在项目的配置文件通过DEFAULT_RENDERER_CLASSES对全局做响应渲染配置:

# 全局使用: settings.py中
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.TemplateHTMLRenderer',
    ],
}

2.源码分析

二次处理响应对象:

# 渲染组件的源码入口: dispatch()方法中的核心源码
def dispatch(self, request, *args, **kwargs):
    try:
        self.initial(request, *args, **kwargs)
        if request.method.lower() in self.http_method_names:
           ...
        else:
            handler = self.http_method_not_allowed
            response = handler(request, *args, **kwargs)
        except Exception as exc:
            response = self.handle_exception(exc)
            
    # 调用APIView的finalize_response()方法二次处理响应对象
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

获取渲染类对象:

# APIVIew的finalize_response()方法的核心源码
def finalize_response(self, request, response, *args, **kwargs):

    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()
        
    return response

# 调用perform_content_negotiation()方法 ---> 调用get_renderers()方法

# get_renderers()核心源码
def get_renderers(self):
	# 通过类属性renderer_classes获取渲染的方式
    return [renderer() for renderer in self.renderer_classes]

class APIView(View):
	# 通过drf的settings获取支持的渲染方式
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    ...
# drf中的settings.py
DEFAULTS = {
    # 默认支持两种渲染方式
    'DEFAULT_RENDERER_CLASSES': [
        # JSON渲染
        'rest_framework.renderers.JSONRenderer',
        # 浏览器渲染
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
    ...
}

3.结论

渲染模块的查找循序为:

  • 自定义类本身的renderer_classes属性
  • 项目settings中的DEFAULT_RENDERER_CLASSES配置
  • drf settings中的DEFAULT_RENDERER_CLASSES配置

默认三种都有。

posted @ 2019-11-19 20:47  17vv  阅读(380)  评论(0编辑  收藏  举报