Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器

news2024/10/6 2:55:55

在这里插入图片描述

系列文章目录

  • Django入门全攻略:从零搭建你的第一个Web项目
  • Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
  • Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
  • Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
  • 跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
  • Django视图层探索:GET/POST请求处理、参数传递与响应方式详解
  • Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘
  • Django API开发实战:前后端分离、Restful风格与DRF序列化器详解
  • Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
  • Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术
  • Django REST framework中GenericAPIView与混入扩展类详解
  • Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器
  • 还在写0.0…

文章目录

  • 系列文章目录
  • 前言
  • 一、ViewSet
    • 1. 视图集是什么
    • 2. action 是什么
    • 3. 视图集功能实现及路由映射
  • 二、ModelViewSet
    • 1. 混入类的视图集概念
    • 2. ModelViewSet视图集功能及路由映射
    • 3. 视图集自定义功能及路由映射
  • 三、DRF路由映射
    • 1. DefaultRouter路由生成
    • 2. SimpleRouter路由生成
    • 3. 两种路由生成方式区别及根路由是什么


前言

    在Django REST framework(DRF)的世界里,ViewSet和ModelViewSet是两大基石,它们为开发者提供了简洁、高效的方式来构建API视图。与此同时,DefaultRouter和SimpleRouter作为路由映射的利器,为API提供了清晰的访问路径。

    本文将带你深入了解ViewSet和ModelViewSet的概念、功能及用法,并解析DefaultRouter与SimpleRouter的区别。


一、ViewSet

1. 视图集是什么

在DRF中,ViewSet 是一种将多个视图逻辑整合到一个类中的方式。它不再像传统的Django视图那样使用 get(), post(), put(), delete() 等方法来处理HTTP请求,而是定义一系列Action动作(如 list(), retrieve(), create(), update(), destroy() 等)来处理不同的HTTP请求。

视图集 简单来说就是一群视图逻辑操作的功能合集,并可采用 路由映射 的方式进行功能选择,编写的内置逻辑方法不再是使用请求命名,而是使用功能来进行命名。

2. action 是什么

视图集类不再实现 getpost 等方法,而是实现动作 actionlistcreate 等,视图集 只在使用 as_view 方法的时候,才会将 action 动作与具体请求方式对应上

例如,下面编写的最基本的视图集:

# views.py
from django.contrib.auth.models import User
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response
class UserViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing or retrieving users.
    """
    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)
    def retrieve(self, request, pk=None):
        queryset = User.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

3. 视图集功能实现及路由映射

视图集的路由映射不是之前的直接 as_view,还要采取对应请求进行映射

# urls.py
path('userlist/', UserViewSet.as_view({'get': 'list'})),
path('userdetail/', UserViewSet.as_view({'get': 'retrieve'})

ViewSet视图集类不再实现get、post等方法,而是实现动作 action 如 list、createl 等。使用视图集ViewSet,可以将一系列逻朝相关的动作放到一个类中:

  • list() 提供一组数据
  • retrieve() 提供单个数据
  • create() 创建数据
  • update() 保存数据
  • destory() 删除数据

二、ModelViewSet

1. 混入类的视图集概念

ModelViewSet 类中继承了 GenericAPIView和各种混入类,在包括用于各种动作实现方式中,各种混入类的行为混合,包含了 .list.retrieve.create.update.partial_update、和 .destroy 等方法,继承了 ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestroyModelMixin,需要至少提供 querysetserializer_class 属性

2. ModelViewSet视图集功能及路由映射

from rest_framework.viewsets import ModelViewSet
class BookModelViewSet(ModelViewSet):
   queryset = Book.objects.all()
   lookup_field = 'pk'
   lookup_url_kwarg = 'pk'
   serializer_class = BookSer

这样具备全部混入类的视图类,只要提供对应数据属性即可完成功能

路由设置:

path('modelviewset/',BookModelViewSet.as_view(
    {'get':'list','post':'create'}
)),
path('modelviewset/<int:pk>/',BookModelViewSet.as_view(
    {'get':'retrieve','put':'update','delete':'destroy'}
)),

3. 视图集自定义功能及路由映射

视图集自定义功能:

from rest_framework.decorators import action

视图集中,通过自定义请求方式,定义方法:
@action(methods=['get'],detail=True)
def getList(self,request,pk):
	...
	return ...

以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。

action装饰器可以接收两个参数:
methods: 声明该action对应的请求方式,列表传递
detail:声明该action的路径是否与单一资源对应
  xxx/<pk>/action方法名/
  
True 表示路径格式是`xxx/<pk>/action方法名/`
False 表示路径格式是`xxx/action方法名/

视图集中附加action的声明

  • 在视图集中,如果想要让Router自动生成我们自定义动作的路由信息,需要使用rest_framework.decorators.action装饰器
  • action装饰器装饰的方法名会作为action动作名,与listretrieve等同
  • action装饰器可以接收三个参数:
    • methods: 声明该action对应的请求方式,列表
    • detail: 声明该action的路径是否与单一资源对应,True:单个数据操作,False:多个数据操作
    • url_path:声明该action的路由尾缀
# views.py
class StudentsModelView(ModelViewSet):
    queryset = Students.objects
    serializer_class = StudentSerializers

    @action(methods=['get'], detail=False, url_path='login')
    def login(self, request):
        """登录"""
        return Response({'message': '成功!!'})

路由文件如下:

from rest_framework.routers import DefaultRouter

from . import views

# 实例化路由类
router = DefaultRouter()

# 注册视图集
router.register('students', views.StudentsModelView)

# 将生成的路由集添加到urlpatterns中
urlpatterns = []
urlpatterns += router.urls

访问方式如下:
http://127.0.0.1:8000/app/students/login/



三、DRF路由映射

对于视图集ViewSet,我们除了可以自己 手动指明请求方式与动作action之间的对应关系 外,还可以 使用drf所提供的路由功能Routers 来帮助我们快速实现路由信息,更加的方便快捷

Routers主要分如下两种:

  • DefaultRouter
  • SimpleRouter

1. DefaultRouter路由生成

在Django REST framework(DRF)中,DefaultRouterrouters 模块提供的一个类,它用于自动为你的应用中的视图集(ViewSets)生成URL模式。使用 DefaultRouter 可以极大地简化URL配置的复杂性,特别是当你的应用包含多个与资源相关的视图集时。

DefaultRouter 为每个视图集自动生成以下URL模式:

  • 列表视图(list view):返回资源对象列表
  • 详情视图(detail view):返回单个资源对象
  • 创建视图(create view):创建新的资源对象
  • 更新视图(update view):更新现有的资源对象
  • 删除视图(delete view):删除资源对象

比如我们编写一个视图集,具备有全部功能,采用ModelViewSet

#views.py
class BookModelViewSet(ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()
  • 注册路由
#urls.py
from rest_framework import routers
# 1.实例化路由对象
router = routers.DefaultRouter() 
# 2.注册生成路由
router.register('book', BookModelViewSet)
# 3.添加路由
urlpatterns += router.urls  
  • 此时生成的路由
app/ ^actions/$ [name='studentmodel-list']
app/ ^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
app/ ^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']
app/ ^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']
app/ [name='api-root']
app/ <drf_format_suffix:format> [name='api-root']
  • 我们看到中间还多了一些路由,是带有format正则匹配的,这些是用来获取纯粹json格式数据
app/ ^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']

app/ ^actions/(?P<id>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-detail']

app/ <drf_format_suffix:format> [name='api-root']
  • 比如直接通过浏览器访问接口地址,默认会返回DRF所提供的页面,但是此时数据被解析成了text/html格式,如果希望得到纯粹的json格式,那么可以利用上面DefaultRouter路由生成的新路由,直接访问如下连接,看到的就是直接的json格式返回,而不是html标签格式
http://127.0.0.1:8000/app/actions.json
#app/ ^actions\.(?P<format>[a-z0-9]+)/?$ [name='studentmodel-list']
  • 注意,除了使用urlpatterns进行路由拼接,还可使用include进行路由分发也是可以的
path('', include(router.urls)),

2. SimpleRouter路由生成

在Django REST framework(DRF)中,SimpleRouterrouters 模块提供的一个类,用于为视图集生成路由URL,它是一个简单的路由,为视图集生成标准的URL模式,且不会添加额外的API根视图等,与 DefaultRouter 相比,它更加简洁,只关注于基本的URL生成功能。

  • 注册路由
from rest_framework import routers
# 1.实例化路由对象
router = routers.SimpleRouter()
# 2.注册生成路由
router.register('actions', IndexActinosView, basename='actions')
# 3.添加路由
urlpatterns += router.urls  
  • 创建好的路由如下所示,虽然你只看到两条路由
    但其实每一条路由后面都映射了可以保留的请求方式及action的映射
app/ ^actions/$ [name='studentmodel-list']
#包含:获取列表get,创建一条信息post
app/ ^actions/(?P<id>[^/.]+)/$ [name='studentmodel-detail']
#包含:获取一条信息get,更新一条信息put,删除一条信息delete
  • 路由对象register方法参数介绍
# 1.实例化路由对象
router = routers.SimpleRouter()
# 2.注册生成路由
router.register('路由命名', 视图集, basename='路由名称前缀')

3. 两种路由生成方式区别及根路由是什么

  • SimpleRouter:最基本的路由映射方式,只会将视图集具备的混入类功能进行路由的生成
  • DefaultRouter:对比与SimpleRouter更加高级,包含有drf根页面的路由,不只是视图集所包含的视图部分
  • 根路由是一个特殊的路由,用于处理对网站根目录的请求,并通常列出所有可用的API端点。

根路由定义:
根路由 通常是一个特殊的路由,它位于路由系统的最顶层,用于处理对网站根目录(如/)的请求。在Django REST framework中,使用DefaultRouter时,会自动生成一个根路由,该路由会列出所有可用的API端点。这使得开发者能够方便地查看和理解API的结构。


在这里插入图片描述

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

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

相关文章

【java】数学运算考试系统

目录 一、登录界面&#xff1a; 二、管理员界面&#xff1a; 三、学生考试界面&#xff1a; 面向小学低年级学生&#xff0c;随机生成两个整数的加减法算式要求学生解答。要求有用 户登录、注册等 GUI 界面&#xff0c;用户数据存入文件&#xff0c;体现面向对象编程思想。 …

windows11子系统Ubuntu 22.04.4子安装图形化界面

1、windows11家庭版本设置 打开虚拟机安装许可 2、Microsoft Store下载安装ubuntu 我使用的是22.04.4 LTS版本 3、 打开ubuntu 命令窗口 1、打开win11的命令行&#xff0c;在下拉三角下标&#xff0c;打开&#xff0c;可以看到有Ubuntu 的选项&#xff0c;点击即可进入linux命…

【Android面试八股文】你说一说什么是双亲委托机制?为什么需要双亲委托机制?

一、双亲委托机制 1.1 双亲委托机制概述 双亲委托机制是指当一个类加载器收到一个类加载请求时, 该类加载器首先会把请求委派给父类加载器。 如果父类加载器还存在父类加载器,则会一直向上委派,直至最终交由顶层的启动类加载器完成类加载, 每个类加载器都是如此,只有在所…

RIP解决不连续子网问题

#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网&#xff0c;被另一个主网分割&#xff0c;例如下面实验拓扑在某公司的网络整改项目中&#xff0c;原先R1 和RS 属于同一主网络 10.0.0.0/8&#xff0c;现被 R2、R3、R4 分离&#xff0c;整网采用了 …

Docker 安装 MySQL5.7 和 MySQL8

文章目录 安装 MySQL5.7拉取镜像前期准备启动容器 安装MySQL8.0拉取镜像查看镜像前期准备启动容器 安装 MySQL5.7 拉取镜像 docker pull mysql:5.7拉下来镜像后 执行 docker images 此时我们已经有这个镜像了。 前期准备 在根目录下创建 app &#xff0c; 在 app 目录下创建…

牛客周赛 Round 47 解题报告 | 珂学家

前言 题解 这真的是牛客周赛&#xff1f; 哭了 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 A. 小红的葫芦 签到题 但是写起来有点变扭&#xff0c;方法应该蛮多的 统计分组 有2组一组长度为2&#xff0c;一组长度为3 def check(arr):arr.sort()if arr[0] …

数据结构试题 20-21

真需要就死记吧 二叉树遍历-先序(非递归)【图解代码】_哔哩哔哩_bilibili 解释一下步骤&#xff1a; 一个循环为&#xff1a; 1.取节点 2.放右子树 3.放左子树 每次循环&#xff0c;都要从栈里取出一个节点 先放右子树&#xff0c;再放左子树 那这道题就是&#xff0c;先放1&am…

内网Docker镜像无法使用?Debian/Ubuntu离线安装Dokcer

离线安装Docker 卸载冲突的包 for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done先删除docker sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin d…

DSP28335:独立按键控制LED灯

做任何事情不可操之过急&#xff0c;虽然我们可能在之前的单片机学过相关的原理&#xff0c;但是一个新的单片机依然有他的学习的地方&#xff0c;之前我觉得很简单&#xff0c;就跳过这个学习&#xff0c;结果到后面就很浮躁&#xff0c;导致后面的内容与这一章相连接的时候&a…

调用第三方系统的签名设计与校验实例讲解与实践

在现代软件开发中&#xff0c;调用第三方系统API已经成为常见需求。为了保证数据传输的安全性和完整性&#xff0c;许多API采用了签名机制。本文将详细讲解如何设计与校验调用第三方系统的签名&#xff0c;以确保双方通信的安全和可靠。 #### 一、签名机制的意义 签名机制主要…

.gitignore文件忽略的内容不生效问题解决

文章目录 ①&#xff1a;现象②&#xff1a;原因③&#xff1a;解决 ①&#xff1a;现象 在已经提交过的git管理的项目中&#xff0c; 新增加一个.gitignore文件&#xff0c;文件内忽略内容不生效或者修改.gitignore文件之后&#xff0c;文件内新增的忽略内容不生效 ②&#…

Dell戴尔灵越Inspiron 16 Plus 7640/7630笔记本电脑原装Windows11下载,恢复出厂开箱状态预装OEM系统

灵越16P-7630系统包: 链接&#xff1a;https://pan.baidu.com/s/1Rve5_PF1VO8kAKnAQwP22g?pwdjyqq 提取码&#xff1a;jyqq 灵越16P-7640系统包: 链接&#xff1a;https://pan.baidu.com/s/1B8LeIEKM8IF1xbpMVjy3qg?pwdy9qj 提取码&#xff1a;y9qj 戴尔原装WIN11系…

1.华为路由器-三层交换机-二层交换机组网连接

AR1配置GE 0/0/0接口IP [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0] [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.1 24 [Huawei]iP route-static 192.168.0.0 16 1.1.1.2三层交换机配置如下 创建vlan [Huawei]vlan batch 10 20配置接口ip [Huawei]int g0/0/1 [Huawei…

【数据结构】排序(下)

个人主页~ 排序&#xff08;上&#xff09; 栈和队列 排序 二、常见排序的实现8、快速排序的优化9、非递归快速排序&#xff08;1&#xff09;基本思想&#xff08;2&#xff09;代码实现&#xff08;3&#xff09;时间复杂度&#xff08;4&#xff09;空间复杂度 10、归并排序…

第二篇: 掌握Docker的艺术:深入理解镜像、容器和仓库

掌握Docker的艺术&#xff1a;深入理解镜像、容器和仓库 1. 引言 1.1 简要介绍Docker的重要性 在当今快速发展的技术世界中&#xff0c;软件开发和部署的效率和可靠性是衡量成功的关键因素。Docker&#xff0c;作为一个开源的容器化平台&#xff0c;革新了软件的打包、分发和…

016基于SSM+Jsp的医院远程诊断系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

知识普及:什么是边缘计算(Edge Computing)?

边缘计算是一种分布式计算架构&#xff0c;它将数据处理、存储和服务功能移近数据产生的边缘位置&#xff0c;即接近数据源和用户的位置&#xff0c;而不是依赖中心化的数据中心或云计算平台。边缘计算的核心思想是在靠近终端设备的位置进行数据处理&#xff0c;以降低延迟、减…

如何看懂SparkUI?

Jobs页面 Stage页面 显示额外的指标和摘要指标&#xff1a; 摘要指标&#xff08;Summary Metrics&#xff09;统计了所有完成的任务的执行行为&#xff0c;包括执行时间、GC时间、输入输出信息等&#xff0c;并提供了最小值&#xff08;Min&#xff09;、第25百分位数&#xf…

Windows环境利用 OpenCV 中 CascadeClassifier 分类器识别人脸 c++

Windows环境中配置OpenCV 关于在Windows环境中配置opencv的说明&#xff0c;具体可以参考&#xff1a;VS2022 配置OpenCV开发环境详细教程。 CascadeClassifier 分类器 CascadeClassifier 是 OpenCV 库中的一个类&#xff0c;它用于实现一种快速的物体检测算法&#xff0c;称…

Java面向对象-final关键字

Java面向对象-final关键字 一、final1、修饰变量2、修饰方法3、修饰类4、案例 一、final 可以修饰变量、方法、类 1、修饰变量 final修饰一个变量&#xff0c;变量的值不可以改变&#xff0c;这个变量就变成一个字符常量&#xff0c;约定俗称的规定&#xff1a;名字大写。 f…