登录/注册
小企鹅
2678
占位
0
占位
0
浏览量
占位
粉丝
占位
关注
Django(51)drf渲染模块源码分析
小企鹅
2021-08-02 09:44:11 2021-08-02
69
0

前言

渲染模块的原理和解析模块是一样,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是怎么配置渲染器的,这样以后我们自定义渲染器也就十分简单了

原文: https://www.cnblogs.com/jiakecong/p/14862223.html

暂无评论