importlib的使用、9个视图子类、视图集、drf之路由、drf之请求响应回顾、GenericViewSet相关流程图

news2024/11/25 7:56:32

一 drf之请求响应回顾

# 1 drf请求
	-请求对象:data,query_params,其他跟之前一样,FILES
    -默认:支持三种编码
    	-局部配置:视图类中
        	-from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
        	-parser_classes = [JSONParser]
            
        -全局配置:
        REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        	],
		}
        
        -全局使用了,局部再换---》视图类改即可
        
# 2 drf响应
	-Response  ---》一定继承了django原生的HTTPResponse
      -data:字典,列表,字符串,空赋值给它---》http响应体中
      -status:http响应状态码  from rest_framework import status
      -headers:响应头
         res=HttpResponse()  res=render()   res=redirect()  res=JsonResponse()四件套之一
            res['name']='lin'  # 放到响应头中
            return res
     -响应编码格式---》一般不动 

# 3 两个视图基类
	-APIView---》写了5个接口
    -GenericAPIView 继承自APIView---》以后跟数据库打交道和要序列化就用它
    	### 重要属性### 
    	-queryset:以后放所有某个表查询出的数据
        -serializer_class:要序列化的类
        
        ### 重要方法###
        -get_queryset  :要序列化的所有数据,qs对象
        -get_serializer :序列化类
        -get_object  :修改,查询,删除 的单条
        
        
# 4 5个视图扩展类
    RetrieveModelMixin, 
    CreateModelMixin, 
    DestroyModelMixin, 
    ListModelMixin, 
    UpdateModelMixin

二 9个视图子类

from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView
from rest_framework.generics import RetrieveAPIView, DestroyAPIView, UpdateAPIView
from rest_framework.generics import RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView

# 以后想写5个接口中的某一个或某几个或所有,只需要选择继承不同的类即可,类中只需要配置两个类属性
	queryset = Publish.objects.all()
    serializer_class = PublishSerializer

1 视图类

#1 想写  publish: 查询所有,查询单条,修改一条,新增一条,删除一条的接口
class PublishView(ListCreateAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer


class PublishDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

#2 想写  publish: 查询单条,新增一条,的接口--->使用9个视图子类编写
class PublishView(CreateAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer


class PublishDetailView(RetrieveAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

#3 想写  publish: 查询单条,新增一条,的接口--->使用5个视图扩展类+GenericAPIView
class PublishView(GenericAPIView,CreateModelMixin):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    def post(self,request,*args,**kwargs):
        return self.create(request,*args,**kwargs)
class PublishDetailView(GenericAPIView,RetrieveModelMixin):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    def get(self,request,*args,**kwargs):
        return self.retrieve(request,*args,**kwargs)

2 路由

path('publish/', PublishView.as_view()),
path('publish/<int:pk>', PublishView.as_view()),

三 视图集

1 ModelViewSet

# 1 只要视图类继承了它,路由写法改一下,5个接口都有了
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    
    
path('publish/', PublishView.as_view({'get':'list','post':'create'})),
path('publish/<int:pk>', PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),

1.1 ModelViewSet源码分析

# 有查询所有接口
	-get--list----》拿到所有数据,序列化--返回
    
# 新增一条
	-post---create---》之前咱们写的新增的代码一样的
    
    
    
# 为什么get 就变成了list
# 为什么post 就变成了create

2 ViewSetMixin

# 没见过
# ViewSetMixin 决定了,以后路由写法就变了
	-path('publish/', PublishView.as_view({'get':'list','post':'create'}))
    -path('publish/', PublishView.as_view({'get':'lqz'}))
    
# 源码分析
	-class GenericViewSet(ViewSetMixin, generics.GenericAPIView):ViewSetMixin必须放前面--》保证执行的as_view是ViewSetMixin的
        
    -请求来了,路由匹配成功---》执行ViewSetMixin的as_view内的view(request)
        def view(request, *args, **kwargs):
            self = cls(**initkwargs) # 类实例化得到对象--》self是谁的对象?PublishView
            self.action_map = actions # {'get':'list','post':'create'}
            # method:get
            # action: list
            for method, action in actions.items():
                # list 方法
                handler = getattr(self, action) #PublishView对象中反射list,拿到了
                # 反射设置值
                #setattr(PublishView视图类的对象,get,list 方法)
                # PublishView视图类的对象中就会有一个get方法,就是list
                setattr(self, method, handler)
            return self.dispatch(request, *args, **kwargs)
# 总结:
	-路由中这样配置:PublishView.as_view({'get':'list','post':'create'})
    -以后get请求过来,本质执行的就是视图类中的list方法

2.1 以后视图类中方法名可以随意命名,只要路由做好映射

# 继承的类是:只要继承ViewSetMixin ,就能视图类中方法任意命名,路由写法变化

3 ReadOnlyModelViewSet

# 以后写的接口,只想有 获取单条和获取所有,继承它

4 视图层中类的总结

# 1 两个视图基类
	-APIView和GenericAPIView
    -APIView的执行流程:包装了新的  处理了csrfrequeset,执行了3大认证,处理全局异常
    -GenericAPIView:要做序列化,要跟数据库打交道,就直接继承它即可
    	-queryset
        -serializer_class
        
        -get_object
        -get_queryset
        -get_serializer
        
        
# 2 5个视图扩展类(不是视图类),需要GenericAPIView才能用
	-快速使用5个接口
    -某几个接口:查询单条,新增一条,的接口--->使用5个视图扩展类+GenericAPIView
    	class PublishView(GenericAPIView,CreateModelMixin)
        	queryset=Publish.objects.all()
        	serializer_class=序列化类
            def post(self,request)
            	return self.create(request)
        class PublishDetailView(GenericAPIView,RetrieveModelMixin)
        	queryset=Publish.objects.all()
        	serializer_class=序列化类
            def get(self,request)
            	return self.retrieve(request)
            
            
# 3 9个视图子类(继承GenericAPIView+5个视图扩展类的组合)
	ListAPIView, CreateAPIView  
    ListCreateAPIView
    
	RetrieveAPIView, DestroyAPIView, UpdateAPIView
	RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
    
    
# 4 视图集
	-ModelViewSet:
    	-ViewSetMixin+GenericAPIView+5个视图扩展类
        -GenericViewSet+5个视图扩展类
        
    -ViewSetMixin源码:路由做映射的配置,以后视图类中方法可以随便命名
    -Viewset:ViewSetMixin+APIView---》不需要序列化,路由写法变了
    -GenericViewSet:ViewSetMixin+GenericAPIView--》需要序列化,需要用数据库,路由写法变化
    -ReadOnlyModelViewSet:list和retrieve

四 drf之路由

# 之前路由写法:
	path('books/', BookView.as_view())
    
# 以后一旦继承了ViewSetMixin,就变成了path('publish/', PublishView.as_view({'get': 'list', 'post': 'create'}))

# 这样写起来,做映射,可能有些麻烦,于是drf,帮咱们封装了两个路由类---》可以帮助咱们快速生成之前咱们写的映射关系


###### 必须是继承ViewSetMixin+APIView及其子类才能自动生成  SimpleRouter  DefaultRouter

## 自动生成路由:自动映射如下:
{'get': 'list', 'post': 'create'}
{'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}


## 其他的-->视图类中有别的方法,我们想做映射,需要使用装饰器

使用方式

# 大前提:必须是继承ViewSetMixin+APIView及其子类才能自动生成
####使用步骤
# urls.py中
#### 1 导入路由类
from rest_framework.routers import SimpleRouter, DefaultRouter
#### 2 类实例化得到对象
router = SimpleRouter()
#### 3 自动生成路由,调用对象的某个方法,完成跟视图类的对应关系,映射路由
router.register('publish', PublishView, 'publish')
# router.register('books', BookView, 'books') #  后期可以注册更多
router.register('user',UserView,'user')
##### 4 把自动生成的路由,加到总路由中
urlpatterns = urlpatterns + router.urls  # 两个列表直接相加

### 第四步可以这样写
	path('api/v1/', include(router.urls)),   # http://127.0.0.1:8008/api/v1/user/register/--->post

1 SimpleRouter, DefaultRouter

SimpleRouter, DefaultRouter区别
	-DefaultRouter生成的路径多一个根路径 api-root
    -DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据
以后就用:SimpleRouter就可以

2 action装饰器

# 作用:为视图类中的方法做路径的映射
	-这些方法需要排除5个 :create,list,destroy,update,retrieve
    
# 使用方式
    @action(methods=['POST'],detail=False)
    def register(self, request):
        return Response('register')
# 自动生成:
	http://127.0.0.1:8008/user/register/---->post--->就会执行register
# action参数
	-methods请求方式,可以写多个
    -detail:路径中是否带id号  
    	http://127.0.0.1:8008/user/register/    # detail=False
        http://127.0.0.1:8008/user/4/register/  # detail=True



*********************** 代码展示 ***********************************
-1.路由
from django.contrib import admin
from django.urls import path
from app01.views import UserView

# 1.导入路由类
from rest_framework.routers import SimpleRouter, DefaultRouter
# 2.类实例化得到对象
router = SimpleRouter()
# 3.自动生成路由,调用对象的某个方法,完成跟视图类的对应关系,映射路由
router.register('user', UserView, 'user')

urlpatterns = [
    path('admin/', admin.site.urls),
    # 访问 login/路径  post请求就会执行UserView中的register方法
    path('register/', UserView.as_view({'post': 'register'})),

]

urlpatterns += router.urls



-2.视图函数
from rest_framework.decorators import action


class UserView(GenericViewSet):
    # http://127.0.0.1:8000/user/register/ ----> post -----> 就是执行 register
    # url_path 是路径后面的名字, 如果不写,就以方法名为路径

    # @action(methods=['POST'], detail=False, url_path='reg')
    # methods 请求方式
    # detail 是否带id

    # @action(methods=['POST'], detail=False)
    @action(methods=['POST'], detail=True)
    # def register(self, request):
    # http://127.0.0.1:8000/user/2/register/
    def register(self, request, pk):
        print(pk)
        # self.get_queryset()
        return Response('register')

3 以后继承ModelViewSet也可也能会重写好多方法

#### 重写list
class PublishView(ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    def list(self, request, *args, **kwargs):  # 以后可能会重写list,做自己的定制
        res=super().list(request, *args, **kwargs)

        return Response({'code':100,'msg':'成功','result':res.data})
    
    
### 重写get_serializer_class
def get_serializer_class(self):  # 是GenericAPIView类中的方法,返回什么,以后就以哪个序列化类继续操作
    print(self.action)
    if self.request.method=='POST':
        return WritePublishSerializer
    else:
        return self.serializer_class

    
### 重写perform_create
def perform_create(self, serializer):
    serializer.save()


### 序列化使用PublishSerializer,反序列化使用 WritePublishSerializer   

4 视图类的对象中的action参数

print(self.action)  
# 视图类的对象中有个action属性---》它是当次请求执行的方法名的字符串

# 通过action可以限制视图类中某个方法使用的序列化类是哪个

importlib的使用

`importlib` 是 Python 标准库中的一个模块,它提供了一种动态导入模块和获取模块信息的方式,
允许你在运行时加载、导入和使用 Python 模块。这对于编写可扩展、灵活的代码和插件系统非常有用。

以下是一些 `importlib` 模块的常见用法示例:

1. **动态导入模块**import importlib

   # 动态导入模块
   module_name = "my_module"
   my_module = importlib.import_module(module_name)

   # 使用动态导入的模块
   result = my_module.my_function()

2. **从模块中导入对象**import importlib

   # 动态导入模块
   module_name = "my_module"
   my_module = importlib.import_module(module_name)

   # 从模块中导入对象
   my_function = getattr(my_module, "my_function")

   # 使用导入的对象
   result = my_function()

3. **重新加载模块**import importlib

   # 动态导入模块
   module_name = "my_module"
   my_module = importlib.import_module(module_name)

   # 重新加载模块
   my_module = importlib.reload(my_module)

4. **获取模块的文件路径**import importlib

   # 动态导入模块
   module_name = "my_module"
   my_module = importlib.import_module(module_name)

   # 获取模块的文件路径
   module_path = my_module.__file__


这些示例演示了如何使用 `importlib` 动态导入模块、从模块中导入对象、
重新加载模块以及获取模块的文件路径。
这些功能可以用于构建插件系统、模块化应用程序和动态加载模块的需求。

五、GenericViewSet相关流程图

1.GenericViewSet继承流程图

在这里插入图片描述

2.minix和GenericViewSet流程图

在这里插入图片描述

3.minix和GenericViewSet关系详情流程图

在这里插入图片描述

六、rest_framework导图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/977951.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的故事——MySQL架构与历史

MySQL架构与历史 文章目录 MySQL架构与历史一、MySQL逻辑架构二、并发控制三、事务四、多版本并发控制(MVCC) 一、MySQL逻辑架构 第一层&#xff1a;连接处理、授权认证、安全等等 第二层&#xff1a;查询解析、分析、优化、缓存以及所有的内置函数。包含跨存储引擎的功能&…

【数据结构与算法】十大经典排序算法

文章目录 前言一、常见十大排序算法总结1、名词解释2、时间复杂度 二、排序算法与C语言实现1、冒泡排序2、选择排序3、插入排序4、希尔排序5、归并排序6、快速排序7、堆排序8、计数排序9、桶排序10、基数排序 总结 前言 排序算法是《数据结构与算法》中最基本的算法之一。 排序…

java:操作cookie

背景 cookie 是一种客户端会话技术&#xff0c;将数据保存到客户端。主要流程就是&#xff1a; 1、服务器把数据设置到cookie并返回给浏览器 2、浏览器自动保存 3、浏览器下一次发送请求自动携带cookie给服务器 我们主要来看一下 java 是怎么操作 cookie 的。 cookie介绍 特…

区块链技术与应用 - 学习笔记2【密码学基础】

大家好&#xff0c;我是比特桃。本系列笔记只专注于探讨研究区块链技术原理&#xff0c;不做其他违反相关规定的讨论。 区块链技术已被纳入国家十四五规划&#xff0c;在“加快数字发展 建设数字中国”篇章中&#xff0c;区块链被列为“十四五”七大数字经济重点产业之一&#…

Node.js安装使用

目录 一、安装 Node.js二、环境变量配置三、npm常用命令 Node.js 是一个强大的运行时环境&#xff0c;它使您能够在服务器端运行 JavaScript 代码。它非常流行&#xff0c;用于构建 Web 应用程序、API 和各种后端服务。 一、安装 Node.js 1、访问 Node.js 官方网站。 在主页上…

算法训练day34|贪心算法 part03(LeetCode 1005.K次取反后最大化的数组和、134. 加油站、135. 分发糖果(处理一边再处理一边))

文章目录 1005.K次取反后最大化的数组和思路分析代码实现 134. 加油站暴力方法贪心方法 135. 分发糖果(处理一边再处理一边)思路分析代码实现思考总结 1005.K次取反后最大化的数组和 题目链接&#x1f525; 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#…

使用redis实现队列功能

使用redis实现队列功能 操作方法描述LPUSHLong lPush(String key, String… values)将一个或多个值 value 插入到列表 key 的表头&#xff0c;返回插入后列表中value的数量&#xff0c;若key不存在&#xff0c;会创建一个新的列表并执行 LPUSH 操作RPOPLPUSHString rPopLPush(S…

hive安装步骤

centos7安装hive&#xff0c;hive版本3.1.2 一、环境准备 JDK版本&#xff1a;jdk-8u381 Hadoop版本&#xff1a;hadoop-3.1.3 MySQL版本&#xff1a;8.0.34 二、hive安装步骤 1.解压 将压缩包复制到/opt/software目录下&#xff0c;并解压至/opt/module/目录 tar -zxf…

bootstrap 导航栏下拉菜单,居右下拉菜单

<!DOCTYPE html> <html lang"en"> <head><!-- 新 Bootstrap5 核心 CSS 文件 --> <link rel"stylesheet" href"bootstrap-5.0.0-beta1-dist/css/bootstrap.min.css"><!-- 最新的 Bootstrap5 核心 JavaScript 文…

Ubuntu22.04 LTS 显卡相关命令

第一部分查看驱显卡信息 一、查看显卡型号 # -i表示不区分大小写 lspci | grep -i nvidia # 必须安装好nvidia驱动 nvidia-smi -L 二、查看显卡驱动版本 cat /proc/driver/nvidia/version 三、查看CUDA、cuDNN版本 # 或者 nvcc -V&#xff08;两个显示的版本一致&#xf…

指针和字符数组笔试题及其解析(第一组)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言&#xff1a; 数组名在寻常情况下表示首元素地址&#xff0c;但有两种情况例外&#xff1a; 1.sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小 2.&数组名&#xff0c;这里的…

【KRouter】一个简单且轻量级的Kotlin Routing框架

【KRouter】一个简单且轻量级的Kotlin Routing框架 KRouter&#xff08;Kotlin-Router&#xff09;是一个简单而轻量级的Kotlin路由框架。 具体来说&#xff0c;KRouter是一个通过URI来发现接口实现类的框架。它的使用方式如下&#xff1a; val homeScreen KRouter.route&l…

C# PSO 粒子群优化算法 遗传算法 随机算法 求解复杂方程的最大、最小值

复杂方程可以自己定义&#xff0c;以下是看别人的题目&#xff0c;然后自己来做 以下是计算结果 private void GetMinResult(out double resultX1, out double min){double x1, result;Random random1 new Random(DateTime.Now.Millisecond* DateTime.Now.Second);min 99999…

创建MyBatis的映射文件模板

Settings->Editor->->Code Style->File and Code Templates <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dt…

tomcat部署、tomcat虚拟主机及tomcat多实例

目录 一、Tomcat概述 tomcat是什么&#xff1f; 什么是 servlet&#xff1f; 什么是 JSP? Tomcat 功能组件结构 Container 结构分析 Tomcat 请求过程 二、Tomcat部署 1、关闭防火墙和selinux&#xff0c;并将Tomcat所需软件包传到/opt目录下 2、安装JDK 3、设置JDK…

MATLAB 2022b 中设置关闭 MATLAB 之前进行询问

在 MATLAB 2022b 中可以进行设置&#xff0c;在关闭 MATLAB 之前进行询问&#xff0c;防止意外关闭 MATLAB。如图&#xff1a;

《Effective STL》读书笔记(一):容器

容器类型&#xff1a; 标准STL序列容器&#xff1a;vector, string, deque, list标准STL关联容器&#xff1a;set, multiset, map, multimap非标准序列容器slist和rope非标准关联容器&#xff1a;hash_set, hash_multiset, hash_map, hash_multimap标准的非STL容器&#xff1a…

LabVIEW利用纳米结构干电极控制神经肌肉活动

LabVIEW利用纳米结构干电极控制神经肌肉活动 随着人口老龄化&#xff0c;长期护理的必要性变得更加重要&#xff0c;医疗中心的压力开始达到惊人的水平。全球对所有社会和经济部门的认识对于更好地协调卫生和社会服务之间的护理以及为更多的院外治疗提供条件至关重要。 关于医…

SSE 和 WebSocket 应用

SSE 和 WebSocket 应用 一.SSE 和 WebSocket 对比二.SSE 和 WebSocket 调试SpringBoot 下 SSE 应用1.依赖2.启动类3.接口类4.Html 测试5.测试结果 SpringBoot 下 WebSocket 应用1.依赖2.启动类3.WS 切点配置4.WS连接类配置5.WS Html 测试6.测试结果 一.SSE 和 WebSocket 对比 …

数据结构与算法-选择冒泡快排

一&#xff1a;选择排序 场景&#xff1a;找出一个班上身高最高的人你会怎么找&#xff1f;A B C D A B 选择排序的思路和插入排序非常相似&#xff0c;也分已排序和未排序区间。但选择排序每次会从未排序区间中找到最小的元素&#xff0c;将其放到已排序区间的末尾。但是不像插…