渲染模板

渲染模板

根据用户请求的RUL向服务器要响应的数据类型,比如:json数据,xml数据,将这些数据向用户返回

一、渲染模板的使用

# 在renderers.py模板模块中导入你要渲染的模板
# JSONRenderer: 返回json数据
# BrowsableAPIRenderer: 返回浏览器html页面

from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
 
# 1.局部配置
# 渲染模块的局部配置
# 局部禁用就是配置空list:[]  # pytthon3.7 有问题
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]

# 2.全局配置
# drf的配置,在drf中settings.py查看如何配置
REST_FRAMEWORK = {
    # 渲染模块的全局配置:开发一般只配置json
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.TemplateHTMLRenderer',
    ],
   
}

img

二、渲染模板的源码解析

# 1 对请求响应进行二次封装
def dispatch(self, request, *args, **kwargs):
    ....
    ....
    # 二次处理响应
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

# 2. 接续配置的渲染类
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()

# 3. 获取渲染对象的类    
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

# 3 renderer_classes 自己全局
 def get_renderers(self):
        """
        Instantiates and returns the list of renderers that this view can use.
        """
        # 从自己的视图类找renderer_classer类属性(局部配置)APIView的类属性(从自己配置文件中找)> 自己的项目配置文件中找(全局配置), drf默认配置问价中找(默认配置)
        return [renderer() for renderer in self.renderer_classes]
    
class BaseRenderer:
    """
    All renderers should extend this class, setting the `media_type`
    and `format` attributes, and override the `.render()` method.
    """
    media_type = None
    format = None
    charset = 'utf-8'
    render_style = 'text'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        raise NotImplementedError('Renderer class requires .render() to be implemented')


总结:

  1. 根据流程,再次进入drf的dispatch方法,该方法对响应数据进行了二次封装,然后,进入self.finalize_response方法
  2. 在self.finalize_respons方法中perform_content_negotiation中获取渲染的对象结果,进入perform_content_negotiation方法
  3. perform_content_negotiation方法中实现了获取配置文件的渲染结果集,通过self.get_renderers()方法
  4. 在self.get_renderers()方法中self.renderer_classes读取配置的渲染对象,先从创建的视图类中(BookAPIView(APIView)(局部配置))找,然后在从自己的项目文件中找(项目中 settings.py,全局配置), 最后从drf默认配置文件中(默认配置)
  5. renderer()是从配置文件中获取到的对应类然后到 renderer.py 文件中获取类对象,创建的类对象(JSONRenderer())返回数据渲染的结果
  6. 核心:可以全局和局部配置视图类支持的结果渲染:默认可以json和页面渲染,学习该模块的目的是开发可以全局只配置json方式渲染
posted @ 2020-02-10 15:49  RandySun  阅读(305)  评论(0编辑  收藏  举报