DRF之APIView类

APIView的基本使用

在使用CBV时,都是需要继承django提供的视图类:View,但如果想要使用drf的功能,就需要继承drf提供的视图类:APIView。

简单使用

在使用之前,需要去注册drf,因为drf也是一个应用。

image

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()),
]

运行,访问这个路由:

image

如果你得到的是这个页面,那么就是成功了。

APIView执行流程分析

在了解APIView执行流程前,需要了解CBV的执行流程:CBV剖析

在路由层,我们调用了APIView类中的as_view方法,可以先查看APIView类中的as_view是如何编写的:

image

重要的代码主要是以下两句:

  • 执行了父类的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。

image

重点

  • 包装了新的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

image

这里先把老的request对象,也就是django的request赋值给了_request变量。

如果想要再APIView中使用老的request对象获取属性,需要这么写:

request._request.POST
request._request.GET
request._request.method

这样太过于麻烦,所以drf的Request类中编写了__getattr__方法:如果request对象没有获取到属性,就去对象中的_request获取属性,也就是去老的request获取属性。

image

drf的Request类还有个data方法,包装成了数据属性:

  • 前端无论什么编码方式传来的数据,都从request.data中取,当字典用即可。
  • django中的request,如果是formdata,urlencoded编码是从POST中取,如果是json,从body中取出来自己转换。

drf的Request类有个query_params方法,包装成了数据属性,也就是django中的request的GET属性。

image

上传文件,跟之前一样用,但是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一样
posted @ 2022-06-14 16:55  Yume_Minami  阅读(285)  评论(0编辑  收藏  举报