DRF基本使用及执行流程分析

介绍:

# 使用的都是CBV的方式 ,继承的类为drf提供的类(提供的类很多)
# 这里目前继承使用APIView类
# 因为APIView是所有类的基类,其他类可能拓展了方法后续会介绍。

基本使用:对比Django来看他们的区别。

# 路由层:这里编写和django的CBV编写方式完全一样
urlpatterns = [path('book2/',views.BookAPIView.as_view()),
]# 拓展:
第二个参数的结果一定是一个函数的内存地址
当请求来的时候会给第二个参数加括号调用并且传一个参数为request
# 视图层:这里继承的类使用drf提供的类为APIView
# 我们在使用Django编写CBV的时候继承的是View
# drf中,自定义了Response类,以后给前端响应都用它,(而django会用HttpResponse,JsonResponse,render,redicet四大响应类)from rest_framework.views import APIView
from rest_framework.response import Responseclass BookAPIView(APIView):def get(self,request,*args,**kwargs):return Response('get请求')# 总结:对比django只是继承的类不一样和返回的不一样

验证响应结果:

# drf的响应给前端的即是Response封装后响应的结果。
# 这个页面的渲染是drf自己封装的模板。

APIView的执行流程(源码分析)

引子:

在了解APIView执行流程需要简单的了解一下CBV源码分析View的执行流程:
地址:https://www.cnblogs.com/garyhtml/p/15955229.html

开始:

1.路由层:

urlpatterns = [path('book2/',views.BookAPIView.as_view()),
]
# 如果有请求来访问book2/的路由,就会执行BookAPIView.as_view(),他的结果一定是一个函数的内存地址然后会自动加括号调用该函数,并将request参数传入# 那么此时执行as_view()就去自己定义的类中BookAPIView查找该方法。

2.查找as_view()方法

# 视图层:
from rest_framework.views import APIView
from rest_framework.response import Responseclass BookAPIView(APIView):def get(self,request,*args,**kwargs):return Response('get请求')# 显然:我们自己定义的类中没有该方法,那么就去继承的APIView中查找

# 我们可以看到在APIView中重写的as_view方法,并且它继承的原来Django的View(所以不基于Django是用不了的)
# 那么此时as_view()方法已经不是View的as_view()方法了,我们来研究重写的这个as_view()方法是怎么编写的

上述:csrf_exempt(view)
相当于:@csrf_exemptdef view():...
# 这样就取消了csrf的保护
# 所以重写的as_view()方法目的只是为了取消csrf中间件的校验。

3.执行View的as_view()方法

# 此时super().as_view(**initkwargs)调用了父类的as_view()方法
# 所以:还要执行:APIView父类View的as_view方法

4.APIView的dispatch方法

# 去APIView中查找dispatch方法:
# 补充快速查找的方法:

# 我们看到在APIView中重写了dispatch方法,那么肯定执行APIView的dispatch。
# 接下来我们就来研究一下APIView中的dispatch方法

5.initialize_request方法

# 我们看到initialize_request的执行,执行结果是Request类序列化的结果,那么上述新的request即为Request序列化产生的对象,并且将老的request传给了这个类,还额外添加了一些功能属性。(这个Request是drf的类)

6.Request类

# 我们看到当Request类加括号时触发内部的__init__方法时,老的request赋值给了self._request,此时self时Request类的对象,那么就是新的request对象,
所以:新的request._request=老的request

7.验证request._request=request

# 实验:request._request=request是否正确
# 如下:
# 我们看到确实老的request是封装到的request._request中
# 新的request确实是Request实例化产生的对象# 那么为什么新的request.GET也可以取到老的request._request.GET相同的结果呢我们来研究一下?

8.重写__getattr__方法

# 补充:
# 对象.属性或者方法的时候会自动触发当前所在类中内部的__getattr__魔法方法
# 魔法方法:不需要主动调用,在某种特定条件下就会自动触发它的执行
# 魔法方法的格式:编写在类中格式:__名字__所以说:此时request.GET就会触发当前所在类Request类的__getattr__方法的执行
# 研究Request中(__getattr__)方法

# 如果新的request.属性没有该属性的话,就会执行__attr__将属性传入给参数attr# 那么原因就找到了:Request中重写的这个__getattr__方法,还是去request._request把attr反射出来,所以还是走的request._request.GET

request:data属性

# 新的request中有一个新的属性 :data- data是post请求携带的数据,返回结果为字典的形式- 在django中我们知道不同的编码格式,存储在不同的方法中如:request.POST取urlencoded编码格式的数据request.body取json格式二进制数据- 那么在drf中,无论什么编码格式,只要是post提交的数据,都在request.data中
# 文件对象还是在request.FILES# 示例:def post(self,request,*args,**kwargs):print(request.data)print(request.POST)return Response('post请求')

总结加补充:APIView和Request对象分析

1 以后如果使用了drf,继承APIView(drf提供了很多view,他们都是继承自APIView),执行流程如下:-包装出了一个新的request,在视图函数中使用时,跟原来没有区别-注意:取post提交的数据,不要从request.POST中取了,要从request.data中取-注意:取get提交的数据,尽量不从request.GET中取了,要从request.query_params中取# 补充:
# query_params方法:@property     # 将方法封装成数据属性def query_params(self):return self._request.GET

2 Request类(drf的)中需要掌握的-request.data         # 方法包装成了数据属性-request.query_params       # 就是request._request.GET-request.FIELS              # 上传的文件-用起来跟原来一样
3 APIView类-包装新的request-执行了认证,权限,频率....-处理了全局异常-包装了response对象

DRF基本使用及执行流程分析 | APIView源码分析相关推荐

  1. 【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★

    文章目录 一.JobServiceContext 引入 二.JobServiceContext 源码分析 三.用户在应用层如何使用 JobScheduler 四.用户提交任务 五.广播接收者监听广播触 ...

  2. Android源码分析--MediaServer源码分析(二)

    在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的B ...

  3. Linux内核 eBPF基础:kprobe原理源码分析:源码分析

    Linux内核 eBPF基础 kprobe原理源码分析:源码分析 荣涛 2021年5月11日 在 <Linux内核 eBPF基础:kprobe原理源码分析:基本介绍与使用>中已经介绍了kp ...

  4. k8s client-go源码分析 informer源码分析(3)-Reflector源码分析

    k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...

  5. 详述 Spring MVC 启动流程及相关源码分析

    文章目录 Web 应用部署初始化过程(Web Application Deployement) Spring MVC 启动过程 Listener 的初始化过程 Filter 的初始化 Servlet ...

  6. 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 )

    文章目录 一.回调 StateChangedListener 接口 二.JobHandler 处理 ( 任务检查 ) 三.maybeRunPendingJobsH 方法 四.assignJobsToC ...

  7. 深入理解Spark 2.1 Core (七):Standalone模式任务执行的原理与源码分析

    这篇博文,我们就来讲讲Executor启动后,是如何在Executor上执行Task的,以及其后续处理. 执行Task 我们在<深入理解Spark 2.1 Core (三):任务调度器的原理与源 ...

  8. 【spring】spring异步执行的使用与源码分析

    在实际的开发过程中,有些业务逻辑使用异步的方式处理更为合理.比如在某个业务逻辑中,需要把一些数据存入到redis缓存中,这个操作只是一个辅助的功能,成功或者失败对主业务并不会产生根本影响,这个过程可以 ...

  9. Netty技术细节源码分析-FastThreadLocal源码分析

    本文是该篇的修正版 本文的github地址:点此 Netty 的 FastThreadLocal 源码解析 该文中涉及到的 Netty 源码版本为 4.1.6. Netty 的 FastThreadL ...

最新文章

  1. ssh升级后+sftp+java_java中使用JSCH包,SFTP及SSH2文件操作及远程命令执行(改进)...
  2. C/C++程序从编译到最终生成可执行文件的过程分析
  3. mui用ajax上拉加载更多,mui上拉加载更多的使用
  4. 详解华为交换机iStack特性
  5. 阿里云mysql创建多个用户_阿里云MySQL创建指定用户访问指定表
  6. python内建函数(不完全)
  7. openssl--生成RSA公钥和私钥
  8. 微信公众号视频下载教程
  9. 解码上市银行手机APP排行 兴业获评分最高
  10. 安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新
  11. 获取海拔高度. 实时气压
  12. 修改sim卡号码 android,android 如何动态修改SIM卡应用名称 MT6572 MT6589
  13. 强化学习入坑之路04
  14. 基于 Self-hosted Debug 的调试
  15. 【C++】STL的简介
  16. 鼠标连点器电脑版安装使用教程
  17. RK3588平台开发系列讲解(DisplayPort篇)DP相关模式说明
  18. 紫色特别舒服的UI趣味测试微信小程序源码下载包含多种评测
  19. 注解类型异常:@ComponentScan ANNOTATION type filter requires an annotation typ
  20. 8.Python中装饰器是什么?

热门文章

  1. 颜语言(网络交往语言)
  2. 笔记本WiFi,蓝牙模块消失解决方法之一
  3. word默认文字环绕方式是什么_Word 2016 中默认的图片与文字的环绕方式是(   )。_智慧树知到答案_学小易找答案...
  4. 人生苦短_感叹人生苦短的句子
  5. R语言自学笔记:向量、矩阵及dataframe基础
  6. 表单上下间隔怎么设置php,html段间距怎么设置
  7. 开放性物流接口调用流程 - 达达物流
  8. 求百米运动员的平均速度
  9. Js-正则替换字符串replace()方法超详细用法
  10. linux同步时间服务器时间配置