• 渲染模板


    渲染模板

    根据用户请求的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方式渲染
  • 相关阅读:
    redis
    docker :no such file or directory
    删除Linux的用户
    lunux系统安全
    centos7.4yum错误
    POI2014 HOT-Hotels
    POI2009 KON-Ticket Inspector
    CF140E New Year Garland
    CF392B Tower of Hanoi
    落谷 P2401 不等数列
  • 原文地址:https://www.cnblogs.com/randysun/p/12291229.html
Copyright © 2020-2023  润新知