Django(51)drf渲染模塊源碼分析

前言

渲染模塊的原理和解析模塊是一樣,drf默認的渲染有2種方式,一種是json格式,另一種是模板方式。
 

渲染模塊源碼入口

入口:APIView類中dispatch方法中的:self.response = self.finalize_response(request, response, *args, **kwargs)
 

渲染模塊源碼分析

我們首先點擊finalize_response進入查看源碼

def finalize_response(self, request, response, *args, **kwargs):
    """
    Returns the final response object.
    """
    # Make the error obvious if a proper response is not returned
    # 斷言是否是HttpResponseBase對象
    assert isinstance(response, HttpResponseBase), (
        'Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` '
        'to be returned from the view, but received a `%s`'
        % type(response)
    )
    
    # 判斷是否是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

上述代碼是響應模塊的源碼,該源碼中包含了渲染模塊的源碼,就是這句neg = 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

代碼中有個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]

這就是渲染器列表的源碼,跟解析器列表的源碼大同小異,接着再點擊renderer_classer查看

renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

到這裡我們就知道了,drf默認的渲染器在settings下的DEFAUIT_RENDERER_CLASSES中,配置如下

'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],

如果我們想局部配置渲染器,只需在自己定義的視圖類中添加render_classes 即可,一般也不用做修改,以上分析只是讓大家知道drf是怎麼配置渲染器的,這樣以後我們自定義渲染器也就十分簡單了

Tags: