一、APIView

  入口

  在路由层执行as_view()方法

  rest-framework/views.py/class APIView/def as_view()

  

  可以看到,APIView继承了Django原生的View,并且重写了as_view()方法,在APIView的as_view方法中,除了一处类中是否有queryset属性的判定,as_view主要实现的功能是将原来返回的函数对象view加入装饰器装饰,使之可以被csrfmiddleware中间件的校验忽略,因为我们无法从前端获取csrf_token。如果不采用这种方法,我们不得不禁用该中间件,这就影响了我们继续正常使用Django原生框架。

  django/views/base.py/class View/def as_view()

  在Django原生的View类的as_view方法中,返回的函数对象view是一个闭包函数,该函数被装饰器csrf_exempt装饰后返回到路由层,在路由层被执行,在执行view时,view返回的是dispatch方法执行的结果。

  在APIView类中重写了dispatch方法,所以上图红框内执行的是APIView的dispatch方法。

  rest-framework/views.py/class APIView/def dispatch()

  

  rest-framework/views.py/class APIView/def initialize_request()

  

  该方法返回了一个Request对象,Request类是一个restframework对Django原生的request进行封装的类,它保留了原生的request对象,作为新实例化request对象的_request属性,并且拥有原生的request对象的所有属性和方法。

  rest-framework/views.py/class APIView/def dispatch()

  

  回到dispatch方法,这里的if判断利用了反射,将我们自己写的get,post等方法取出,且让变量handle指向该方法。self.http_mehtod_names是一个列表,其中包含HTTP八个请求名称的字符串(['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'])。

  

  rest-framework/views.py/class APIView/def finalize_response()

  

  我们看到,在finalize_response函数中,传入了response参数,并且对其进行了一些封装,加入了属性,以及用断言进行校验。

  response是handle调用后返回的结果,handle则是我们自己写的对应HTTP请求的方法,我们在方法中最后返回了一个HttpResponse对象。在dispatch方法中,主要是用反射,对HTTP请求的类型进行对应方法的分发。

二、Request类

  rest-framework/request.py/class Request

  

  可以看到,Django原生的request对象被作为参数传入,封装进了restframework Request类实例化对象的_request属性中,在实例化时,还给新的Request对象加入了新的属性和方法。其中Empty是一个用来占位的空白类。

  当我们想执行Django原生的request对象的方法或者想要获取原生request对象的属性时,在class Request中重写了__getattr__(self,attr)方法,该魔法方法在对象获取属性时,当该对象找不到属性时执行。

  rest-framework/request.py/class Request/def __getattr()__

  

  当新request对象的属性或者方法不存在时,在原生的request对象中寻找,如果也不存在,会抛一个AttributeError异常,这里做了异常捕获后,交给__getattribute__()去执行。在Response中没有重写__getattribute__()方法,当属性不存在时,重写的__getattr__截获了属性查找,如果_request仍然没有找到该属性,就要交给新式类自己的__getattribute__去执行,以保证该类的属性查找正常运行。

三、Serializer

  restframework/serializers.py/class Serializer

 

  Serializer类继承了BaseSerializer,并且没有重写__init__和__new__方法,所以当该类实例化产生对象的时候,调用的是父类BaseSerializer的__init__和__new__方法。

  restframework/serializers.py/class BaseSerializer

  

  先执行__new__方法,实例化一个空对象,在实例化对象的时候,有可能以关键字传参的形式传入many参数,该参数在__new__方法中被**kwargs接受,放入字典中。

  __new__中的if判断是将many取出,当many的Boolean值为false或者many参数没有传入的时候,不执行if下面的语句,也就是会正常实例化一个对象,__new__并未对对象的创建过程做拦截。如果many中有值并且其Boolean不为false时,会执行many_init方法。

  restframework/serializers.py/class BaseSerializer/def many_init()

  在执行many_init方法时,返回的是一个ListSerializer对象。具体执行过程已经在图上标出。

  将QuerySet对象而不是数据对象作为参数,进行序列化时,必须写many=True(必须用关键字传参的形式)。

Django-rest-framework源码分析(一)的更多相关文章

  1. Django rest framework源码分析(3)----节流

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  2. Django rest framework源码分析(1)----认证

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  3. Django rest framework 源码分析 (1)----认证

    一.基础 django 2.0官方文档 https://docs.djangoproject.com/en/2.0/ 安装 pip3 install djangorestframework 假如我们想 ...

  4. Django rest framework源码分析(一) 认证

    一.基础 最近正好有机会去写一些可视化的东西,就想着前后端分离,想使用django rest framework写一些,顺便复习一下django rest framework的知识,只是顺便哦,好吧. ...

  5. Django rest framework源码分析(4)----版本

    版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Mo ...

  6. Django rest framework源码分析(2)----权限

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  7. 3---Django rest framework源码分析(3)----节流

    Django rest framework源码分析(3)----节流 目录 添加节流 自定义节流的方法  限制60s内只能访问3次 (1)API文件夹下面新建throttle.py,代码如下: # u ...

  8. Django之REST framework源码分析

    前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...

  9. Django Rest Framework源码剖析(八)-----视图与路由

    一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...

  10. Django Rest Framework源码剖析(三)-----频率控制

    一.简介 承接上篇文章Django Rest Framework源码剖析(二)-----权限,当服务的接口被频繁调用,导致资源紧张怎么办呢?当然或许有很多解决办法,比如:负载均衡.提高服务器配置.通过 ...

随机推荐

  1. Win10+WSL2+Ubuntu 18.04(WSL下)+VS Code(Win10下)+TexLive 2019(Ubuntu下)安装和配置

    本人手头电脑是Win10 Home版全新安装的系统,由于不想在新系统盘里面安装TexLive导致固态硬盘不断扩大,所以,考虑安装Ubuntu做为WSL,然后把TexLive安装在Ubuntu,并通过V ...

  2. 无线个人区域网WPAN

    无线个人区域网WPAN (Wireless Personal Area Network) 1.1.概述 在个人工作地方把属于个人使用的电子设备用无线技术连接起来自组网络,不需要使用接入点 AP. 整个 ...

  3. scrapy post payload的坑及相关知识的补充【POST传参方式的说明及scrapy和requests实现】

    一.问题及解决: 在用scrapy发送post请求时,把发送方式弄错了. 本来应该是 application/x-www-form-urlencoded  弄成了application/json. 但 ...

  4. python数组和字符串互相转换

    字符串转数组 str = '1,2,3' arr = str.split(',') 数组转字符串 arr = ['a','b'] str = ','.join(arr) arr = [1,2,3] s ...

  5. mongoDb性能提升

    最近在弄MongoDB的时候 发现只按照官网的方式进行操作的话,性能不行,想着用单例模式封装一下,提升一下性能,代码如下: //引入mongodb相关的模块 const MongoClient = r ...

  6. 初识 “HTML”

    HTML 什么是HTML? ①全称:超文本标记语言②超文本:在普通的文本内容的基础上添加超链接.图片.视频等③标记语言:HTML提供一系列标签④版本:HTML 4.01 HTML声明 1.编码格式:H ...

  7. 前端面试题-url、href、src

    一.URL的概念 统一资源定位符(或称统一资源定位器/定位地址.URL地址等,英语:Uniform Resource Locator,常缩写为URL),有时也被俗称为网页地址(网址).如同在网络上的门 ...

  8. 每日一点:git 与 github 区别

    絮絮叨叨在前:以前的公司,都用svn 进行代码管理.最近我那程序猿先生真的受不了我,强迫我使用tortoiseGit. 一开始对于 git 和 github 傻傻分不清,干脆自己整理资料,总结一下. ...

  9. 对Ajax的原理的理解和使用

    1.什么是ajax? AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方 ...

  10. Python 执行 javascript PyExecJS 模块

    PyExecJS 安装 pip install PyExecJS PyExecJS 的基本使用: >>> import execjs >>> execjs.eval ...