python-django rest framework框架之dispatch方法源码分析

1.Django的 CBV 中在请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发 get/post/put等方法

class APIView(View):
    def dispatch(self, request, *args, **kwargs):#1.1 把wsgi的request进行封装
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request     #此时的self.request 是rest_framework的Request对象,它里面比wsgi的request多了一些东西

        try:
            #1.2 进行 初始化     :版本,认证,权限,访问频率
            self.initial(request, *args, **kwargs)
            #1.3 反射执行get等方法
            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

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)
        #1.4 把返回的response 再进行封装
        self.response = self.finalize_response(request, response, *args, **kwargs)
        #1.5 返回
        return self.response

第1.1步:

from rest_framework.request import Request

class APIView(View):
    def initialize_request(self, request, *args, **kwargs):
       #返回了一个rest_framework的Request对象
        return Request(
            request,       #1.1.1
            parsers=self.get_parsers(),        #1.1.2
            authenticators=self.get_authenticators(),       #1.1.3
            negotiator=self.get_content_negotiator(),
        )

第1.1.1步:

pass

第1.1.2步:

class APIView(View):
    def get_authenticators(self):     #self.authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES  是从配置文件中取数据,从变量名不难看出有可能是很多类的列表
        return [auth() for auth in self.authentication_classes]     #self.authenticators = 一个多个对象的列表

第1.2步:

class APIView(View):
    def initial(self, request, *args, **kwargs):     #版本相关     version, scheme = self.determine_version(request, *args, **kwargs)
        #1.2.1认证相关
        self.perform_authentication(request)
        #1.2.2权限相关
        self.check_permissions(request)
        #1.2.3访问频率相关
        self.check_throttles(request)

第1.2.1步:

class APIView(View):
    def perform_authentication(self, request):
     #1.2.1.1
        request.user

第1.2.1.1步:

class Request(object):
    @property
    def user(self):       #此时的self 是 rest_framework的request对象
        if not hasattr(self, ‘_user‘):
            with wrap_attributeerrors():          #1.2.1.1.1
                self._authenticate()
        return self._user

第1.2.1.1.1步:

class Request(object):
    def _authenticate(self):
        #此时的self 是 rest_framework的request对象
        for authenticator in self.authenticators:          #self.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          #赋值,  request.user和request.auth 并返回
                self.user, self.auth = user_auth_tuple
                return
        self._not_authenticated()

第1.3步: 反射执行get等方法

最后、我们可以自定义一个简单的用户认证

class MyAuth(object):
    def authenticate(self,request):
        return "1111","222"

class Host(APIView):
    authentication_classes=[MyAuth]
    def get(self,request):
        print(request.user)    #1111
        print(request.auth)   #222
        return HttpResponse("666")

原文地址:https://www.cnblogs.com/liuwei0824/p/8418998.html

时间: 2024-11-08 21:33:50

python-django rest framework框架之dispatch方法源码分析的相关文章

Django REST framework之序列化组件以及源码分析+全局、局部Hook

序列化两大功能 a.对queryset类型进行序列化 b.对用户请求的数据进行校验 a.对queryset类型进行序列化 举例说明: 表设计 1 from django.db import models 2 3 4 class UserGroup(models.Model): 5 title = models.CharField(max_length=32) 6 7 8 class UserInfo(models.Model): 9 user_type_choices = ( 10 (1, '普

MyBatis框架的使用及源码分析(十一) StatementHandler

我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Excecutor执行sql操作的最终都调用了StatementHandler 来执行,我们拿SimpleExecutor来看: public int doUpdate(MappedStatement ms, Object parameter) throws SQLException { Statement st

Java split方法源码分析

Java split方法源码分析 1 public String[] split(CharSequence input [, int limit]) { 2 int index = 0; // 指针 3 boolean matchLimited = limit > 0; // 是否限制匹配个数 4 ArrayList<String> matchList = new ArrayList<String>(); // 匹配结果队列 5 Matcher m = matcher(inp

invalidate和requestLayout方法源码分析

invalidate方法源码分析 在之前分析View的绘制流程中,最后都有调用一个叫invalidate的方法,这个方法是啥玩意?我们来看一下View类中invalidate系列方法的源码(ViewGroup没有重写这些方法),如下: /**  * Mark the area defined by dirty as needing to be drawn. dirty代表需要重新绘制的脏的区域  * If the view is visible, onDraw(Canvas) will be c

【集合框架】JDK1.8源码分析之Collections &amp;&amp; Arrays(十)

一.前言 整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析.可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析. 二.Collections源码分析 2.1 类的属性   2.2 构造函数 private Collections() { } 说明:私有构造函数,在类外无法调用. 2.3 方法分析 下面是Collections的所有方法. 可以看到,Collections的方法包含了各种各样的操作.下面分析最常用的方法. 1. sort函数 该函数有两个重载函

【集合框架】JDK1.8源码分析之Collections &amp;&amp; Arrays

一.前言 整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析.可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析. 二.Collections源码分析 2.1 类的属性 public class Collections { // 二分查找阈值 private static final int BINARYSEARCH_THRESHOLD = 5000; // 反向阈值 private static final int REVERSE_THRESHOLD = 1

jQuery实现DOM加载方法源码分析

传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但是onload事件触发过于缓慢,尤其是在存在很多外部图片或者视频文件的时候,为了更好的了解这一点有必要知道一个html文档是如何进行加载的,这里引用一个园友的表述: 1.用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件: 2.浏览器开始载入htm

jQuery.pushStack()原型方法源码分析

这次分析的方法跟前面不同,虽然pushStack也是原型方法之一,但是我们几乎从不用在页面调用,在参考手册里面也没有这个方法的使用说明,但是这个方法还是非常重要的,在使用很多jQuery的其他方式都会隐式的调用此方法: 它为以下方法提供支持:? ? jQuery 对象遍历:.eq()..first()..last()..slice()..map().? ? DOM 查找.过滤:.find()..not()..filter()..closest()..add()..andSelf().? ? DO

jQuery.extend()方法和jQuery.fn.extend()方法源码分析

这两个方法用的是相同的代码,一个用于给jQuery对象或者普通对象合并属性和方法一个是针对jQuery对象的实例,对于基本用法举几个例子: html代码如下: <!doctype html> <html> <head> <title></title> <script src='jquery-1.7.1.js'></script> </head> <body> <img src=''/>