drf的基本使用、APIView源码分析和CBV源码拓展
cbv源码拓展
扩展,如果我在Book视图类中重写dispatch方法
-可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果
def dispatch(self, request, *args, **kwargs):
# 请求执行前代码
response=super().dispatch(request, *args, **kwargs)
# 请求执行后代码
return response
# 这样你的get、post...请求来的时候和结束后就会执行自定义的代码
DRF基本使用及执行流程分析(3星)
基本使用
在views.py中
from rest_framework.views import APIView # 继承这个类
from rest_framework.response import Response # 这个是drf封装的
class BookAPIView(APIView):
def get(self, request, *args, **kwargs):
return Response('get请求')
def post(self, request, *args, **kwargs):
return Response('post请求')
在urls.py中
from app01 import views
urlpatterns = [
path('book/', views.BookAPIView.as_view())
]
APIView执行流程(源码分析)
0. APIView继承了django的View
1. APIView中重写了as_view
@classmethod
def as_view(cls, **initkwargs):
# 调用父类的as_view
view = super().as_view(**initkwargs)
# 只要继承APIView以后所有的视图都没有csrf保护了,不管是否注释掉中间件
return csrf_exempt(view)
2 再执行self.dispatch()---->APIView的dispatch
def dispatch(self, request, *args, **kwargs):
# 包装了一个新的request对象,基于原来的request对象包装你的
# 这个request对象是新的request对象,是drf提供的Request类的对象
# 新的request包含,原来老的request(django的request)
# self._request = request(老)
request = self.initialize_request(request, *args, **kwargs)
#print(request._request) 老的request对象
try:
# 认证,权限,频率。。。
self.initial(request, *args, **kwargs)
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
#视图类中get或其他请求方法的执行
response = handler(request, *args, **kwargs)
except Exception as exc:
# 如果在视图类中有错误,会被捕获(全局异常处理)
response = self.handle_exception(exc)
#把response包装了一下,返回了
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
3 在视图类中使用的request对象是新的request对象,老的是request._request
-新的request.GET拿到的还是老的GET,原理如下(Request类重写了__getattr__)
def __getattr__(self, attr):
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
4 结论:以后继承了APIView后,request对象成了新的,但是跟原来一样用
5 新的request对象中有一个属性 data
-data是post请求携带的数据----》字典
-无论是什么编码格式,只要是post提交的数据,都在request.data中
-以后再取值,都从request.data中取
总结
以后如果使用了drf, 继承了APIView(drf提供了很多view, 他们都是继承了APIView), 执行流程如下:
1.包装了一个新的request,在视图函数中使用时,跟原来没有区别
2.POST请求在request.data中取
3.GET请求在request.query_params中取
Request类(drf的)中需要掌握的
- request.data 方法包装成了数据属性
- request.query_params 就是request._request.GET
- request.FIELS 还是取上传的文件
APIView类
- 包装了新的request
- 执行了认证,权限,频率...
- 处理了全局异常
- 包装了response对象