首页 > 其他分享 >DRF06-视图架构

DRF06-视图架构

时间:2023-01-10 23:55:46浏览次数:50  
标签:架构 get self request 视图 DRF06 方法 view

本文探究Django以及DRF的视图的层层递进,从源码学习视图的不断完善和丰富

01 最简单的视图 FBV

urlpatterns = [
    path('test01/', views.test01)
]

只要在浏览器上请求 http://127.0.0.1:8000/book/test01/
就可以看到 test01 被调用

需要注意的是,Django决定出发哪个视图函数或者方法的时候,跟请求的方法类型是没有关系的,请求的方法只是请求的参数而已,在FBV模式下,不管test01是什么请求方法都可以出发test01

02 视图类CBV

为什么会有视图类?
首先很多接口属于同一个模块,典型的就是对于数据的增删查改,其实是围绕同一个功能或者模块儿来实现的。另外我们经常将一个页面或者模块下的所有的接口集成到一个视图类中,方便管理,在视图类中,可能多个方法的部分代码具备高度相似性,因此可以抽取出来作为公共方法,给多个接口调用,因此视图类更方便开发和管理。

Django 中的视图类都需要继承 from django.views.generic import View 因为他有一个核心的方法 as_view方便调用

下面看一下视图的简单使用

class TestView(View):

    def get(self, request):
        print("调用了get方法")
        return HttpResponse('TestView GET')

    def post(self, request):
        print("调用了get方法")
        return HttpResponse('TestView POST')

    def put(self, request):
        print("调用了get方法")
        return HttpResponse('TestView PUT')

urlpatterns = [
    path('test01/', views.test01),
    path('testview/', views.TestView.as_view())
]

通过postman分别使用 get,post,put方法测试一下

可以看到,只是在路由那里写了一个 views.TestView.as_view(), django 程序就可以依据不同的请求方式映射到不同的函数上去执行。
这时 as_view 方法的功劳,接下来我们就去 as_view 方法中去一探究竟

as_view 方法被我单独复制出来,并且删减了一些注释,方便放在一张截图之中,as_view 的核心内容被我圈为3块。下面一块一块得解释

1:参数验证块儿

http_method_names 就是常见的网络请求方法
initkwargs 使我们调用 as_view 的时候传递的参数,as_view 是可以传递参数的,只是我们这里没传,这段代码校验参数是为了防止参数里面有内容覆盖了那些网络请求方法,为什么会这样,我们后面会解释,然后还校验了这些传递的参数必须是当前视图类存在的,不存在也会报异常

2:核心视图方法
view这个内部类是最核心的视图方法,
self = cls(**initkwargs)是使用当前视图类构建了一个对象,并将传递给 as_view 的初始化参数传递给这个视图类对象

def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    if hasattr(self, "get") and not hasattr(self, "head"):
        self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs

setup方法干了什么事,如果当前对象有 get 属性,但是没有 head 属性的话,就让 head 属性指向 get 属性,同时将 request 这个网络请求对象赋值给 当前视图类对象了,args 和 kwargs 是网络请求传递的参数,例如我们经常看到这样的url

http://127.0.0.1:8000/book/test01/19/20/?name=张三

其中这个19和20可以通过url映射规则,提取为请求的参数,并放进 kwargs 中。这里我们可以尝试将 View 源码拷贝出来,然后在 setup 方法中打印 args 和 kwargs,最后让我们的自定义视图类集成拷贝出来的 View 类,就会出发setup 中的打印行为。当然这种行为在 java 中是不可能成功的, Java是强类型语言,而 python 是弱类型语言,鸭子类型,只要有同名方法,皆可以调用。

我对自定义视图类和 as_view 中的 setup 方法做了如下的改动

class TestView(View):

    def get(self, request, pk1, pk2):
        print(pk1, pk2)
        print(self.request)
        print(request)
        print(self.kwargs)
        print("调用了get方法")
        return HttpResponse('TestView GET')

def setup(self, request, *args, **kwargs):
    print(args, kwargs)
    """Initialize attributes shared by all view methods."""
    if hasattr(self, "get") and not hasattr(self, "head"):
        self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs

path('testview/<int:pk1>/<int:pk2>/', views.TestView.as_view())

使用 postman 发起 get 请求,pycharm 控制台打印了如下内容

依据打印结果,可以发现,19和20分别被映射为 pk1 和 pk2,在Python代码中,def func(a,b,c=10) 这样的函数均可以使用 func(q=1,b=2,c=3) 来实现调用
另外 setup 函数将 request 对象和 kwargs 都赋给了视图类对象,因此在视图类中可以直接使用 self.request 和 self.kwargs 可以直接调用
事实证明 self.request 和传递给 get 的 request 是同一个对象,self.kwargs 也可以取用

紧接着 view 方法调用了 dispatch 方法,这个方法也是一个灵魂方法

dispatch 方法通过解析请求中的方法通过反射的方式获取自定义视图类中的和网络请求同名的方法。
因此 自定义视图类最后可能调用的方法必须是网络请求的那些方法名

3:返回这个 view 方法

因此CBV模式的本质还是 FBV,只是利用反射机制做了网络请求方法和视图类同名方法之间的映射

标签:架构,get,self,request,视图,DRF06,方法,view
From: https://www.cnblogs.com/yaowy001/p/17041569.html

相关文章

  • 三层架构登录注册功能
    publicinterfaceUserMapper{/***根据用户名和密码查询用户对象*@paramusername*@parampassword*@return*/@Select("select*f......
  • 三层架构增删改查功能
    ppublicinterfaceBrandMapper{/***查询所有*@return*/@Select("select*fromtb_brand")@ResultMap("brandResultMap")List<Brand>......
  • SSIS【Foreach 循环容器_Foreach ADO.NET 架构行集枚举器】(循环导入一个Excel所有工作
    SQLServer2008R2SSIS_Foreach循环容器_ForeachADO.NET架构行集枚举器(循环导入一个Excel所有工作簿)1.本节主要是循环把工作簿Sheet1、Sheet2、Sheet3中的数据插入到数据......
  • HDFS核心概念与架构
    HDFS简介HDFS是Hadoop项目的核心子项目,在大数据开发中通过分布式计算对海量数据进行存储与管理,它基于流数据模式访问和处理超大文件的需求而开发,可以运行在廉价的商用服务器......
  • MapReduce核心概念及架构
    MapReduce简介MapReduce常用于对大规模数据集(大于1TB)的并行运算,或对大数据进行加工、挖掘和优化等处理。MapReduce将并行计算过程高度抽象到了两个函数map和reduce中,程序员......
  • ZooKeeper核心概念和架构
    ZooKeeper简介ZooKeeper是一个分布式应用程序协调服务,主要用于解决分布式集群中应用系统的一致性问题。它能提供类似文件系统的目录节点树方式的数据存储,主要用途是维护和监......
  • Vue搭建项目的完整流程 如何搭建一个完整的vue项目 vue项目架构
    vue项目架构技术栈:vue3、vue-router、vuex(和pinia)、elementplus、axios、ts、sass1、安装vue3脚手架+tsvuecreateadmin2、分析目录结构node_modules......
  • MySQL24 - 视图
    视图View使用简单、数据安全、数据独立=将SELECT语句封装视图(View)是虚拟存在的表,并不在数据库中真实存在,在使用视图时动态生成视图只保存查询的SQL逻辑,不保存查询......
  • 软件架构设计 - 01 操作系统
     1、零拷贝(【内核区】内存缓存区-Socket缓冲区映射) 2、内存映射(【内核区】内核内存缓冲区-【用户区】应用程序内存) 3、Reactor和Proactor模式    Reactor......
  • k8s运行mysql主从架构
    namespacemysql-ns.yamlapiVersion:v1kind:Namespacemetadata:labels:kubernetes.io/metadata.name:wgs-mysqlname:wgs-mysql创建ns#kubectlapply......