DRF之APIView类
APIView的基本使用
在使用CBV时,都是需要继承django提供的视图类:View,但如果想要使用drf的功能,就需要继承drf提供的视图类:APIView。
简单使用
在使用之前,需要去注册drf,因为drf也是一个应用。
CBV:继承APIView,并且使用drf提供的返回方法:Response,这个方法相当于HttpResponse+JsonResponse结合体,会自动转换。
from rest_framework.views import APIView
from rest_framework.response import Response
class BookAPIView(APIView):
def get(self, request):
return Response('abc')
路由层:与继承View的CBV一样,调用as_view()。
urlpatterns = [
path('api/books/', views.BookAPIView.as_view()),
]
运行,访问这个路由:
如果你得到的是这个页面,那么就是成功了。
APIView执行流程分析
在了解APIView执行流程前,需要了解CBV的执行流程:CBV剖析
在路由层,我们调用了APIView类中的as_view方法,可以先查看APIView类中的as_view是如何编写的:
重要的代码主要是以下两句:
- 执行了父类的as_view方法,也就是django提供的View类(APIView类继承了View类)。
view = super().as_view(**initkwargs)
- 是csrf装饰器取消了csrf校验。
return csrf_exempt(view)
重点:APIView类中的as_view方法就是在View类中的as_view方法的基础上,添加了去除了csrf校验的功能。
但是还不止如此,View类中的as_view返回了dispatch方法,因为在APIView中存在一个dispatch方法,所以APIView.as_view()返回的是APIView.dispatch。
重点:
-
包装了新的request对象,已经不是 django 的request对象了:
-
django 的 request 对象类型:
<class 'django.core.handlers.wsgi.WSGIRequest'>
-
drf 的 request 对象类型:
<class 'rest_framework.request.Request'>
-
-
在执行视图函数之前,执行了三大认证,类似于中间件的功能。
-
处理了全局异常,执行三大认证和视图函数期间,如果出了错,都能统一处理。
-
包装了响应对象。
Request对象源码分析
drf中Request对象入口:
from rest_framework.request import Request
这里先把老的request对象,也就是django的request赋值给了_request变量。
如果想要再APIView中使用老的request对象获取属性,需要这么写:
request._request.POST
request._request.GET
request._request.method
这样太过于麻烦,所以drf的Request类中编写了__getattr__方法:如果request对象没有获取到属性,就去对象中的_request获取属性,也就是去老的request获取属性。
drf的Request类还有个data方法,包装成了数据属性:
- 前端无论什么编码方式传来的数据,都从request.data中取,当字典用即可。
- django中的request,如果是formdata,urlencoded编码是从POST中取,如果是json,从body中取出来自己转换。
drf的Request类有个query_params方法,包装成了数据属性,也就是django中的request的GET属性。
上传文件,跟之前一样用,但是drf把它重写了。
重点:
- django中的request保存到了drf的request._request中。
- 可以跟原生django的request一样使用。
- 前端提交的数据都可以从request.data中取。
- 原生django获取文件要用request.FILES,获取post数据要用request.POST,获取json数据要用request.body并反序列化。
- drf中获取文件、post数据、json数据都用request.data,获取json数据时会自动反序列化。
- 请求地址中的数据都从request.query_params中取,也就是与request.GET一样