前言

渲染模組的原理和解析模組是一樣,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是怎麼配置渲染器的,這樣以後我們自定義渲染器也就十分簡單了