#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response class TestView(APIView): def get(self, request, *args, **kwargs):
# self.dispatch
print(request.user)
print(request.auth)
return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')

Django rest_Framework的基本流程:请求刚进来,会执行dispatch方法,大概的流程如下:第一步封装request,第二步:版本

第三步:认证->request.user,第三步:权限->self.check_permissions(request),第四步:节流self.check_throttles(request)

以前就是Django rest_Framework的基本流程。

认证的源码如下(只有认证源码流程):

在上面刚开始请求进来,先不执行自己写的方法,如:(get、post、put),它会先执行dispatch方法,如果没有,就回去它的父类去找。

执行它父类的dispach

Django rest framework流程:

  原来用CBV的时候它继承from django.views import View中的views方法,在写get,post方法 如:class HostView(view)

  如果有Django rest Framework它就不用继承from django.views import View中的views方法,而是:

  先导入:from rest_framework.views import APIView它就会继承APIView,不在继承django的views如:class     AuthView(APIView):


from rest_framework.views import APIView          先导入APIView 
from django.shortcuts import render,HttpResponse
class AuthView(APIView):                          继承APIView
authentication_classes=[]
def get(self,request):return Response('....’)

而在class AuthView(APIView)中它继承的APIView,而APIView它有继承了view,view它在rest_framework view 中如下图:

点击view它就会到django的view中,而这个view是以前CBV 中的那个view,如下图:

继承的这个类比原来django的这个类跟多了点功能,而它的本质还是和原来的一样先执行dispatch,自己有就执行自己的,没有就执行父类的,父类如果没有它就执行原来的dispatch 。

虽然以前它的本质一样但是现在却发生变化,现在它的request是rest_framework中的request,而原来的request是django中的request,如:

class HostView(APIView):

    def get(self,request,*args,**kwargs):
# 原来request对象,django.core.handlers.wsgi.WSGIRequest
# 现在的request对象,rest_framework.request.Request\
self.dispatch 请求进来先执行dispatch
print(request.user)
print(request.auth)
return Response('主机列表')

1、请求进来先执行dispatch,而dispatch它在APIView中,dispatch在它里面有,先执行它自己,如果把它先删除它就会先执行默认的那个就是django提供,如下图:

请求进来它源码就是从现在开始如下:

源码的第一步:

    def dispatch(self, request, *args, **kwargs):    请求进来先执行dispatch
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args dispatch先把参数获取到
self.kwargs = kwargs
#1、对request进行加工
'''
源码进来的第一步 1、request对象中(它比原来的类中封装了好多):
         request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), 这里面放的是两个列的对象
negotiator=self.get_content_negotiator(),
parser_context=parser_context
        '''
request = self.initialize_request(request, *args, **kwargs) 在这执行了这个方法,它返回了request
self.request = request
self.headers = self.default_response_headers # deprecate? try:
第二步:2
self.initial(request, *args, **kwargs) # Get the appropriate handler method
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
第三步:3.执行get/post/delete/put等函数
response = handler(request, *args, **kwargs) 返回结果 except Exception as exc:
response = self.handle_exception(exc)
第四步:4、对返回结果再次加工
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

在执行 request = self.initialize_request(request, *args, **kwargs)时,先去自己写的找,没有再去父类找,上面是自己没有就去父类找,如下图:

上面没有就去拿它的静态字段,如下图:

在这上面执行时request被加工,如下图:

源码执行的第二步:

    def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
2.1处理版本信息
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
2.2认证授权
self.perform_authentication(request)
2.3权限验证
self.check_permissions(request)
2.4请求用户限制访问频率
self.check_throttles(request)

执行源码第二步中的2.2认证授权:

 def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
self.perform_authentication(request) 执行这一步,点击就去如下图:
self.check_permissions(request)
self.check_throttles(request)
还是先找自己的,没有才执行以下的:  
def perform_authentication(self, request):
"""
Perform authentication on the incoming request. Note that if you override this and simply 'pass', then authentication
will instead be performed lazily, the first time either
`request.user` or `request.auth` is accessed.
"""
request.user 在这里request是传过来的request,不是原来的request

尽接着下一步它就会找user,如下图:

找到user :

def user(self):
"""
Returns the user associated with the current request, as authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'): 如果没有user
self._authenticate() 就会这行self._authenticate()这个方法,在找到这个方法
return self._user
    def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
循环对象列表
for authenticator in self.authenticators: 在这里authenticators是那个对象列表,它循环这个对象列表
try:
执行每一个对象authenticate方法
user_auth_tuple = authenticator.authenticate(self) 在这里它返回了两个值
except exceptions.APIException: 没有验证成功就会报错
self._not_authenticated()
raise if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple 这里self.auth,self.user,就会有值,验证成功就会通过
return self._not_authenticated()

Python之Django rest_Framework框架源码分析的更多相关文章

  1. Django搭建及源码分析(三)---+uWSGI+nginx

    每个框架或者应用都是为了解决某些问题才出现旦生的,没有一个事物是可以解决所有问题的.如果觉得某个框架或者应用使用很不方便,那么很有可能就是你没有将其使用到正确的地方,没有按开发者的设计初衷来使用它,当 ...

  2. Django如何启动源码分析

    Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...

  3. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  4. Android Small插件化框架源码分析

    Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github ...

  5. YII框架源码分析(百度PHP大牛创作-原版-无广告无水印)

           YII 框架源码分析    百度联盟事业部——黄银锋 目 录 1. 引言 3 1.1.Yii 简介 3 1.2.本文内容与结构 3 2.组件化与模块化 4 2.1.框架加载和运行流程 4 ...

  6. Spark RPC框架源码分析(一)简述

    Spark RPC系列: Spark RPC框架源码分析(一)运行时序 Spark RPC框架源码分析(二)运行时序 Spark RPC框架源码分析(三)运行时序 一. Spark rpc框架概述 S ...

  7. Spark RPC框架源码分析(二)RPC运行时序

    前情提要: Spark RPC框架源码分析(一)简述 一. Spark RPC概述 上一篇我们已经说明了Spark RPC框架的一个简单例子,Spark RPC相关的两个编程模型,Actor模型和Re ...

  8. Spark RPC框架源码分析(三)Spark心跳机制分析

    一.Spark心跳概述 前面两节中介绍了Spark RPC的基本知识,以及深入剖析了Spark RPC中一些源码的实现流程. 具体可以看这里: Spark RPC框架源码分析(二)运行时序 Spark ...

  9. nodejs的Express框架源码分析、工作流程分析

    nodejs的Express框架源码分析.工作流程分析 1.Express的编写流程 2.Express关键api的使用及其作用分析 app.use(middleware); connect pack ...

随机推荐

  1. (๑•̀ㅂ•́)و✧随笔总目录ヾ(≧▽≦*)o

    SSM整合进阶篇 日常手记 开源博客My Blog系列 短信接口攻击事件 读书笔记 SSM整合优化篇 SSM整合基础篇 SSM整合进阶篇 Spring+SpringMVC+MyBatis+easyUI ...

  2. 【转】adb操作命令详解及大全

    adb是什么?:adb的全称为Android Debug Bridge,就是起到调试桥的作用.通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具.a ...

  3. bzoj 2303: [Apio2011]方格染色

    传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 ...

  4. jvm内存模型-回收算法-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东面试题)

    1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个 ...

  5. SQL强化(三) 自定义函数

    ---恢复内容开始--- Oracle中我们可以通过自定义函数去做一些逻辑判断,这样可以减少查询语句,提高开发效率 create  -- 创建自定义函数 or replace -- 有同名函数就替换, ...

  6. cesium编程入门(三)开始使用cesium开发

    搭建最简的开发环境 这一节来搭建一个最简单的能运行的helloworld,以后的代码也会在这一节的基础上慢慢增加 创建文件夹 mkdir cesium-test cd cesium-test 引入编译 ...

  7. 《你不知道的JavaScript上卷》知识点笔记

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...

  8. LNMP下FTP服务器的安装和使用(Pureftpd和Proftpd)

    FTP是网站文件维护中使用比较多的,目前LNMP一键安装包中有Pureftpd和Proftpd服务器安装脚本,LNMP默认不安装任何FTP服务器,需要用户自行安装(1.2开始不再提供proftpd的安 ...

  9. UILabel的顶对齐解决方法

    对于有多行文字的UILabel而言,需要设置UILabel的numberoflines属性,此属性默认是1,也就是只显示一行,多余的会以尾部,中间的方式进行截断,具体要看你的初始设置. 在这里可以将其 ...

  10. MYSQL DISTINCT Optimization

    在很多情况下,Distinct和order by的组合需要建立一个内存临时表.  因为distinct关键字可能利用group by,所以了解下mysql如何处理group by有帮助. distin ...