八、(重点)视图集ModelViewSet自定义action路由routers

news2024/11/25 5:00:11

上一章:

七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值_做测试的喵酱的博客-CSDN博客

下一章:

九、DRF生成API文档_做测试的喵酱的博客-CSDN博客

一、视图集ModelViewSet与ReadOnlyViesSet

ModelViewSet视图集 与 ReadOnlyViesSet视图集

1、ModelViewSet视图集:支持增删改查,如果需要对某个模型进行增删改查操作,才会选择ModelViewSet

2、ReadOnlyViesSet视图集:只支持读取操作,如果仅仅只对某个模型进行数据读取操作(取列表数据接口、获取详情数据接口),一般会选择ReadOnlyModelViewSet。

二、视图集ModelViewSet

ModelViewSet是一个最完整的视图集类。

1、提供了获取列表数据接口、获取详情数据接口、创建数据接口、更新数据接口、删除数据的接口(增删改查接口)

2、如果需要对某个模型进行增删改查操作,才会选择ModelViewSet
3、如果仅仅只对某个模型进行数据读取操作(取列表数据接口、获取详情数据接口),一般会选择ReadOnlyModelViewSet

class ProjectViewSet(viewsets.ModelViewSet):
    """
    list:
    获取项目列表数据

    retrieve:
    获取项目详情数据

    update:
    更新项目信息

    names:
    获取项目名称

    """

    queryset = Projects.objects.all()
    serializer_class = ProjectModelSerializer

    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['=name', '=leader', '=id']
    ordering_fields = ['id', 'name', 'leader']

    # 可以在类视图中指定分页引擎类,优先级高于全局
    pagination_class = PageNumberPagination

2.0 类视图的设计原则


 a.类视图尽量要简单
 b.根据需求选择相应的父类视图
 c.如果DRF中的类视图有提供相应的逻辑,那么就直接使用父类提供的
 d.如果DRF中的类视图,绝大多数逻辑都能满足需求,可以重写父类实现
 e.如果DRF中的类视图完全不满足要求,那么就直接自定义即可 

2.1 自定义视图集方法action

场景:当视图集默认提供的方法,不能满足需求时,可以自定义action方法。

    @action(methods=['GET'], detail=False)
    def names(self, request, *args, **kwargs):
        # queryset = self.get_queryset()
        # queryset = self.filter_queryset(queryset)
        # names_list = []
        # for project in queryset:
        #     names_list.append({
        #         'id': project.id,
        #         'name': project.name
        #     })
        # serializer = self.get_serializer(queryset, many=True)
        #
        # # return Response(names_list, status=200)
        # return Response(serializer.data, status=200)
        return super().list(request, *args, **kwargs)

2.1.1 函数定义

2.1.2 action装饰 

@action(methods=['GET'], detail=False, url_path='xxx', url_name='yyyy')

如果需要使用路由器机制自动生成路由条目,那么就必须得使用action装饰器
1、methods(非必填)指定需要使用的请求方法,如果不指定,默认为GET
2、detail(必填)指定是否为详情接口,是否需要传递当前模型的pk值
     如果需要传递当前模型的pk值,那么detail=True,否则detail=False
3、url_path指定url路径,默认为action方法名称
4、url_name指定url路由条目名称后缀,默认为action方法名称

127.0.0.1:8000/projects/names/

127.0.0.1:8000/projectsxxx/$[name='projects-yyy']

   @action(detail=True)
    def interfaces(self, request, *args, **kwargs):
        project = self.get_object()
        interfaces_qs = project.interfaces_set.all()
        interfaces_data = [{'id': interface.id, 'name': interface.name} for interface in interfaces_qs]
        return Response(interfaces_data, status=200)

127.0.0.1:8000/projects/12/interfaces/
 

三、路由 routers

3.1 SimpleRouter路由

引入

from rest_framework import routers

1、可以使用路由器对象,为视图集类自动生成路由条目
2、路由器对象默认只为通用action(create、list、retrieve、update、destroy)生成路由条目,自定义的action不会生成路由条目
3、创建SimpleRouter路由对象
 

router = routers.SimpleRouter()

4、使用路由器对象调用register方法进行注册

router.register(r'projects', views.ProjectViewSet)
  1. prefix指定路由前缀,如上r‘projects’
  2. viewset指定视图集类,不可调用as_view,如上views.ProjectViewSet
     

5、设置路由条目

方式一:路由器对象.urls属性可获取生成的路由条目

urlpatterns = [
  
    # 路由器对象.urls属性可获取生成的路由条目
    path('', include(router.urls)),
]

方式二:两个路由列表相加


# router.urls为列表
urlpatterns += router.urls

3.2 DefaultRouter路由

创建SimpleRouter路由对象

router = routers.SimpleRouter()

创建DefaultRouter路由对象

router = routers.DefaultRouter()


 DefaultRouter与SimpleRouter功能类似,仅有的区别为:DefaultRouter会自动生成一个根路由(显示获取数据的入口)

3.3 自定义action的路由处理

方式一:@action装饰器处理路由

自定义的action,不会自动生成路由,需要引入@action装饰器处理。

    @action(methods=['GET'], detail=False)
    def names(self, request, *args, **kwargs):
 
        return super().list(request, *args, **kwargs)

    @action(detail=True)
    def interfaces(self, request, *args, **kwargs):
        project = self.get_object()
        interfaces_qs = project.interfaces_set.all()
        interfaces_data = [{'id': interface.id, 'name': interface.name} for interface in interfaces_qs]
        return Response(interfaces_data, status=200)

 # 1、如果需要使用路由器机制自动生成路由条目,那么就必须得使用action装饰器
    # 2、methods指定需要使用的请求方法,如果不指定,默认为GET
    # 3、detail指定是否为详情接口,是否需要传递当前模型的pk值
    #   如果需要传递当前模型的pk值,那么detail=True,否则detail=False
    # 4、url_path指定url路径,默认为action方法名称
    # 5、url_name指定url路由条目名称后缀,默认为action方法名称
    # @action(methods=['GET'], detail=False, url_path='xxx', url_name='yyyy') 

方式二:在urls.py文件中,指定路由

​​​​​​​

四、同一个视图集ModelViewSet中,对同一个模型类不同形式的输出

场景:

一个视图集ModelViewSet,下有多个action方法,比如获取list 、获取数据详情retrieve

这两个action获取的是同一个序列化器类。

当我要求获取数据列表与获取详情的内容 展示字段不同。

4.1 视图集ModelViewSet 采用多个序列化器类

场景:

一个视图集ModelViewSet,下有多个action方法,比如获取list 、获取数据详情retrieve

这两个action获取的是同一个序列化器类。

当我要求获取数据列表与获取详情的内容 展示字段不同时,需要采用多个序列化器类。

一个视图集ModelViewSet,如何使用多个action对应多个序列化器?

重写get_serializer_class 方法。

    def get_serializer_class(self):
        """
        a.可以重写父类的get_serializer_class方法,用于为不同的action提供不一样的序列化器类
        b.在视图集对象中可以使用action属性获取当前访问的action方法名称
        :return:
        """
        if self.action == 'names':
            return ProjectsNamesModelSerailizer
        else:
            # return self.serializer_class
            return super().get_serializer_class()

4.2 重写action方法

场景:

一个视图集ModelViewSet,下有多个action方法,比如获取list 、获取数据详情retrieve

这两个action获取的是同一个序列化器类。

当我要求获取数据列表与获取详情的内容 展示字段不同时,重写action方法。

将多余的返回值干掉

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(request, *args, **kwargs)
        response.data.pop('id')
        response.data.pop('create_time')
        return response

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

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

相关文章

基于FPGA:运动目标检测(包围盒仿真工程,及一些调试问题)

目录 前言一、安装器件库二、仿真工程操作1、进入文件列表2、找到bounding_box_locate.vt,双击打开文件3、修改路径4、路径设置5、切换回“Hierarchy”,即工程界面6、运行仿真7、查看波形 重点:调试问题三、仿真代码1、仿真顶层文件2、绘制包…

node篇-fs模块儿

nodejs-fs模儿 异步 1. mkdir() 创建一个目录 // 1.mkdir 创建一个目录,回调函数的参数含义:err const fs require(fs); fs.mkdir(./avater,(err)>{console.log(err);if(err && err.code EEXIST){console.log(当前目录已经存在)} }) 当我…

华硕天选4R FA617原装Windows11原厂预装系统工厂模式恢复安装带 ASUSRecevory 一键还原22H2版本

华硕天选4R FA617X原装Windows11原厂预装系统工厂模式恢复安装带ASUSRecevory一键还原 文件地址:https://pan.baidu.com/s/1Pq09oDzmFI6hXVdf8Vqjqw?pwd3fs8 提取码:3fs8 华硕工厂恢复系统 ,安装结束后带隐藏分区以及机器所有驱动软件 需准备一个16…

浅谈NoSQL数据库

数据库 数据库,又称为数据管理系统,是处理的数据按照一定的方式储存在一起,能够让多个用户共享、尽可能减小冗余度的数据集合,简而言之可视为电子化的文件柜——存储电子文件的处所。 数据库有:Oracle数据库、ACCESS数…

代码随想录算法训练营第四十五天 | 力扣 70. 爬楼梯(进阶), 322. 零钱兑换, 279.完全平方数

70. 爬楼梯(进阶) 题目 70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 改为:一步一个台阶,两个台阶,三个台阶&#xff…

【浅学 JDBC】

浅学JDBC 笔记记录 一、1. JDBC的概念2. JDBC快速入门2.1 DriverManager2.2 Connection2.3 Statement2.4 ResultSet 3. JDBC入门案例使用3.1 查询所有学生信息3.2 根据id查询学生信息&&新增学生信息&&修改学生信息&&删除学生信息 一、 1. JDBC的概念 …

中科易安8周年,与你相约联网智能门锁

中科易安与物联网技术发展同频 持续推动安防信息化建设 打造多场景应用的数智化通行解决方案 促进技术与安全精准对接 联网智能门锁技术硬核 中科易安打造集NB-IoT、Sub-1G Cat.1、Wifi、RS485和BLE 5.0 在内的六大通信技术组网方案 以“联网”赋能智能门锁 实现通行数…

C++11之atomic原子操作

atomic介绍 多线程间是通过互斥锁与条件变量来保证共享数据的同步的,互斥锁主要是针对过程加锁来实现对共享资源的排他性访问。很多时候,对共享资源的访问主要是对某一数据结构的读写操作,如果数据结构本身就带有排他性访问的特性&#xff0c…

chatgpt赋能python:Python中的等待:理解和优化

Python中的等待:理解和优化 Python是一种强大的编程语言,在构建各种应用程序时很常用。但是,随着应用程序越来越复杂,需要等待一些操作时,Python中的等待传统上会导致性能下降。在这篇文章中,我们将深入了…

可持续能源技术改变世界

文章目录 一、你在工作或生活中接触过可持续能源技术吗?可以分享下你的经历与看法。二、你认为可持续能源技术的优势和挑战有哪些?三、你了解过可持续能源技术的应用现状吗?四、对于可持续能源技术真的否改变世界这个问题你怎么看&#xff1f…

ifconfig工具与驱动交互解析(ioctl)

Linux ifconfig(network interfaces configuring) Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态,或是显示目前的设置。同netstat一样,ifconfig源码也位于net-tools中。源码位于net-tools工具包中&am…

《消息队列高手课》课程笔记(七)

如何使用异步设计提升系统性能? 异步设计如何提升系统性能? 假设我们要实现一个转账的微服务 Transfer(accountFrom, accountTo, amount),这个服务有三个参数:分别是转出账户、转入账户和转账金额。 这个例子的实现过程中&…

chatgpt赋能python:Python中如何反转字符串:三种简单方法

Python中如何反转字符串:三种简单方法 当我们在处理字符串时,有时需要将其反向排列。在Python中,这可以通过以下三种简单方法实现: 1. 使用内置的切片方法 在Python中,可以使用字符串的切片方法将其反转。这种方法非…

(浙大陈越版)数据结构 第三章 树(上) 3.4 小白专场:树的同构(PTA编程题讲解)

题意理解和二叉树表示 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换变成T2,则称两棵树是“同构”的。 eg1:现请你判断如下两棵树(左侧为T1,右侧为T2)是否为同构树? 显然T1可以通过有限次左右孩子…

REST风格 -- SpringMVC入门保姆级教程(四)

文章目录 前言四、REST风格1.了解REST风格2.REST风格写法一般步骤3.REST风格快速开发4.REST风格中的注解5. 案例:基于REST风格页面数据交互 总结 前言 为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然&#…

Redis高级篇 - 分布式缓存

分布式缓存 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: 1.Redis持久化 Redis有两种持久化方案: RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件)&#xff0c…

iPad触屏笔哪个牌子好用?Apple Pencil的平替笔

从无纸化的广泛使用,电容笔成为无纸化中不可替代的一部分。但由于原装电容笔的昂贵,市面上的电容笔品牌众多,不知如何下手,今天给大家推荐几款好用又平价的Apple Pencil平替笔。顺便给不知道如何挑选电容笔的小伙伴科普一下电容笔…

车载网络测试 - CANCANFD - 基础篇_02

目录 七、与CAN总线相关的标准 1、ISO 11898,ISO16845 2、SAE J1939,ISO 11783,NMEA 2000,CANopen 3、ISO15765/ISO14229 4、ISO 17356/OSEK 5、CCP(CAN Calibration Protocol) 6、GMLAN,VWTP,FNOS,DCNet,MCNet 八、CAN总线的特点 九、CAN总线基本概念 七、与CAN总线相…

机器学习-4 决策树算法

决策树算法 算法概述分类算法与分类器决策树算法树模型决策树的原理决策树算法的关键决策树构造的基本思路 算法基本思想决策树的训练与测试三种经典的决策树生成算法基于信息增益的ID3算法基于信息增益率的C4.5算法C4.5算法C5.0算法 基于基尼系数的CART算法 算法流程算法关键问…

chatgpt赋能python:Python中的包

Python中的包 对于使用Python进行编程的开发者来说,包是一个非常重要的概念。包可以看作是一个包含了多个模块的文件夹,这些模块可以在代码中使用。通过使用Python中的包,开发者可以使代码更加模块化,提高代码的可维护性和可读性…