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