rest_framework APIView源码
2020-03-19 本文已影响0人
eeert2
===============================
提前说明,像rest_framework
这种框架,会包含大量的验证,配置,包装
,这些代码很重要,但不是我们要关注的主要逻辑,这里不具体展示,有需要的可以自己查看。
==============================
一、入口点
我们对APIView
主要使用as_view()
方法,所以我们的讲解也从as_view
说起。
二、源码流程
1. rest_framework.views.APIView
的as_view()
方法
在APIView
中的as_view()
主要做了两件事情:
- 1.调用父类的
as_view()
,这里指django
的View
类
super().as_view(**initkwargs)
- 2.对视图函数执行
csrf豁免
return csrf_exempt(view)
2.django.views.View
的as_view()
方法
而在django
的View
中,as_view()
主要执行dispatch(request, *args, **kwargs)
def as_view(cls, **initkwargs):
"""request - response 的主要入口点"""
# 验证参数是否合法
def view(request, *args, **kwargs):
# 验证以及配置参数
return self.dispatch(request, *args, **kwargs) #这是重点
# 配置,包装参数给`view`
return view
as_view
是request - response
的主要入口点,它返回一个可调用对象view
,django
经路由匹配该view
,并自动为可调用对象view
两侧添加()
,执行view()
。
所以这里的view()
函数必须要返回一个response
响应对象。
而view()
函数内部又调用了dispatch()
,所以返回response
的重任就交给了dispatch()
3.rest_framework.views.APIView
的dispatch()
函数
由于APIView
重写了dispatch()
,所以实际执行rest_framework.views.APIView.dispatch()

4.APIview
的dispatch()
方法
def dispatch(self, request, *args, **kwargs):
# 1. 对`request`进行包装
request = self.initialize_request(request, *args, **kwargs)
self.request = request
try:
# 2. 版本,内容格式,用户验证,权限检查,访问频率
self.initial(request, *args, **kwargs)
# 3. 获取`适配`的处理方法,也就是我们写的`get`,`post`,`delete`,`put`,`update`
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 4.执行处理方法
# 例如请求方法为`post`请求,则执行`post(request, *args, **kwargs)`
response = handler(request, *args, **kwargs)
# 5.处理异常
except Exception as exc:
response = self.handle_exception(exc)
# 6 对返回内容进行处理,加工,渲染
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response