viewsets.ViewSet 详解

news2024/10/7 14:28:54

目录

零、前提(这一段可以忽略)

一、地址

二、viewsets.ViewSet介绍

2.1 viewsets.ViewSet介绍

三、viewsets.ViewSet默认方法(增删改查等方法)

四、 生成路由

4.1  使用路由器注册 viewset,自动生成 URL 配置(推荐)

4.2  自定义路由

五、ViewSet actions

五、反射ViewSet actions

六、自定义actions

6.1、http请求put方法、delete方法

八、获取操作的URL


相关文章:

Django项目生成Swagger_做测试的喵酱的博客-CSDN博客

viewsets.ModelViewSet详解_做测试的喵酱的博客-CSDN博客

零、前提(这一段可以忽略)

1、我先创建一个Django项目,Projects app。

python3 manage.py startapp Projects

2、setting.py 注册 Projects app

3、定义模型类models.py

from django.db import models



class Projects(models.Model):
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
    name = models.CharField('项目名称', max_length=200, unique=True, help_text='项目名称')
    leader = models.CharField('负责人', max_length=50, help_text='项目负责人')
    tester = models.CharField('测试人员', max_length=50, help_text='项目测试人员')
    programmer = models.CharField('开发人员', max_length=50, help_text='开发人员')
    publish_app = models.CharField('发布应用', max_length=100, help_text='发布应用')
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, default='', help_text='简要描述')
    update_datetime = models.DateTimeField(auto_now=True, null=True, blank=True, help_text="修改时间",
                                           verbose_name="修改时间")
    create_datetime = models.DateTimeField(auto_now_add=True, null=True, blank=True, help_text="创建时间",
                                           verbose_name="创建时间")

    class Meta:
        db_table = 'tb_projects'
        verbose_name = '项目信息'
        verbose_name_plural = verbose_name
        ordering = ('id',)

    def __str__(self):
        return self.name

4、序列化器类serializers.py

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2023 - 07 -04
# @File: serializers.py
# desc:
from rest_framework import serializers
from .models import Projects

class ProjectsModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Projects
        exclude = ('update_datetime', )
        extra_kwargs = {
            "create_datetime": {
                "read_only": True,
                "format": "%Y年%m月%d日 %H:%M:%S"
            }
        }

一、地址

官方地址: 

Viewsets - Django REST framework

相关文章:

二、viewsets.ViewSet介绍

2.1 viewsets.ViewSet介绍

1、引入:

from rest_framework import viewsets

2、 viewsets.ViewSet 是一个提供了用于处理 CRUD(创建、读取、更新和删除)操作的视图集合。

  • .list():列出所有项目的列表,
  • .retrieve():检索某一个项目的详细信息
  • .create() : 创建一条数据
  • update(): 更新列表
  • .partial_update():更新一条数据
  • .destroy():删除数据

以上方法,是定义的默认方法。需要自己在方法下,补充具体的实现逻辑。

3、继承关系

class ViewSet(ViewSetMixin, views.APIView):

4、项目架构

三、viewsets.ViewSet默认方法(增删改查等方法)

  • .list():列出所有项目的列表,
  • .retrieve():检索某一个项目的详细信息
  • .create() : 创建一条数据
  • .update(): 更新列表
  • .partial_update():更新一条数据
  • .destroy():删除数据

自定义视图类ProjectsViewSet,继承viewsets.ViewSet。手动实现以上方法的逻辑。

from django.shortcuts import render

# Create your views here.
from rest_framework import viewsets, status
from .models import Projects
from .serializers import ProjectsModelSerializer
from rest_framework.response import Response

from rest_framework import viewsets
from rest_framework.response import Response
from .serializers import ProjectsModelSerializer
from .models import Projects

class ProjectsViewSet(viewsets.ViewSet):
    def list(self, request):
        """
        获取所有项目列表
        """
        # 获取所有项目对象
        projects = Projects.objects.all()
        # 将项目对象序列化为 JSON 数据
        serializer = ProjectsModelSerializer(projects, many=True)
        return Response(serializer.data)

    def create(self, request):
        """
        创建新的项目
        """
        # 将请求数据传递给序列化器
        serializer = ProjectsModelSerializer(data=request.data)
        if serializer.is_valid():
            # 保存新创建的项目对象
            serializer.save()
            return Response(serializer.data, status=201)
        else:
            return Response(serializer.errors, status=400)

    def retrieve(self, request, pk=None):
        """
        获取特定项目详情
        """
        # 获取特定的项目对象
        project = Projects.objects.get(pk=pk)
        serializer = ProjectsModelSerializer(project)
        return Response(serializer.data)

    def update(self, request, pk=None):
        """
        更新特定项目
        """
        # 获取特定的项目对象
        project = Projects.objects.get(pk=pk)
        # 将请求数据与项目对象绑定
        serializer = ProjectsModelSerializer(project, data=request.data)
        if serializer.is_valid():
            # 保存更新后的项目对象
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=400)

    def destroy(self, request, pk=None):
        """
        删除特定项目
        """
        # 获取特定的项目对象
        project = Projects.objects.get(pk=pk)
        # 从数据库中删除项目
        project.delete()
        return Response(status=204)

    def partial_update(self, request, pk=None):
        """
        部分更新特定项目
        """
        # 获取特定的项目对象
        project = Projects.objects.get(pk=pk)
        # 将请求数据与项目对象绑定,通过 partial=True 允许部分更新
        serializer = ProjectsModelSerializer(project, data=request.data, partial=True)
        if serializer.is_valid():
            # 保存部分更新后的项目对象
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=400)

您可以使用路由器将此 ViewSet 注册,以自动生成用于列出和检索用户的必要 URL。

注意:

1、在视图类ProjectsViewSet中,create方法,创建数据。

    def create(self, request):
        """
        创建新的项目
        """
        # 将请求数据传递给序列化器
        serializer = ProjectsModelSerializer(data=request.data)
        if serializer.is_valid():
            # 保存新创建的项目对象
            serializer.save()
            return Response(serializer.data, status=201)
        else:
            return Response(serializer.errors, status=400)

serializer.save() 方法,调用的是序列化器类ProjectsModelSerializer 的create方法。

当使用 ModelSerializer 类创建序列化器时,它会自动为你生成默认的 create 方法。这个默认的 create 方法会在视图类调用创建对象的逻辑时被调用。

当你在视图类中调用 serializer.save() 或者 serializer.create(validated_data) 方法时,会触发序列化器中的 create 方法执行。默认的 create 方法会根据传入的验证数据(validated_data)创建并保存模型实例。

如果你在 ModelSerializer 类中重写了 create 方法,并在其中添加了自定义的逻辑,那么在视图类中调用 serializer.save() 或者 serializer.create(validated_data) 方法时,将会执行你自定义的 create 方法。

因此,视图类中的 create 方法和 ModelSerializer 类中的 create 方法在处理创建对象的逻辑时是相关联的。你可以利用这两个方法来完成对对象创建的个性化定制和扩展。

四、 生成路由

4.1  使用路由器注册 viewset,自动生成 URL 配置(推荐)

 使用路由器注册 viewset,并自动生成 URL 配置。

urls.py

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2023 - 07 -04
# @File: urls.py
# desc:
from .views import ProjectsViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'projects', ProjectsViewSet, basename='projects')
urlpatterns = router.urls

启动项目,查看swagger文档,这就生成了增删改查的接口。

4.2  自定义路由

# -*- coding:utf-8 -*-
# @Author: 喵酱
# @time: 2023 - 07 -04
# @File: urls.py
# desc:
from django.urls import path
from .views import ProjectsViewSet

# 创建一个实例作为视图集
projects_viewset = ProjectsViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

# 创建一个用于单个项目的实例
project_detail_viewset = ProjectsViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

urlpatterns = [
    path('projects/', projects_viewset, name='projects-list'),
    path('projects/<int:pk>/', project_detail_viewset, name='projects-detail'),
]

我们首先将 ProjectsViewSet 视图集实例化为 projects_viewset

我们将 "GET" 请求映射到 list 方法,

将 "POST" 请求映射到 create 方法。

然后,我们创建了一个用于单个项目的视图集实例 project_detail_viewset

我们将 "GET" 请求映射到 retrieve 方法,

将 "PUT" 请求映射到 update 方法,

将 "PATCH" 请求映射到 partial_update 方法,

将 "DELETE" 请求映射到 destroy 方法。

最后,我们将 URL 映射到相应的视图集方法并命名它们。可以根据需要调整 URL 模式和命名。

五、ViewSet actions

REST framework 中提供的默认路由器将为一组标准的创建/检索/更新/删除样式的操作提供路由,如下所示:

(其实就是第四节讲的内容)

class ProjectsViewSet(viewsets.ViewSet):
    """
    Example empty viewset demonstrating the standard
    actions that will be handled by a router class.

    If you're using format suffixes, make sure to also include
    the `format=None` keyword argument for each action.
    """

    def list(self, request):
        pass

    def create(self, request):
        pass

    def retrieve(self, request, pk=None):
        pass

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

    def destroy(self, request, pk=None):
        pass

五、反射ViewSet actions

在调度期间,ViewSet 上可以使用以下属性:

  • basename - 用于创建 URL 名称的基础部分。
  • action - 当前动作的名称(例如,list、create)。
  • detail - 布尔值,指示当前动作是否为列表视图或详细视图配置的。
  • suffix - 视图集类型的显示后缀 - 与 detail 属性相同。
  • name - 视图集的显示名称。该参数与 suffix 互斥。
  • description - 视图集中各个视图的显示描述。

您可以检查这些属性以根据当前动作调整行为。例如,您可以类似于以下示例将权限限制为除了 list 动作之外的所有权限:

def get_permissions(self):
    """
    实例化并返回此视图所需的权限列表。
    """
    if self.action == 'list':
        permission_classes = [IsAuthenticated]
    else:
        permission_classes = [IsAdminUser]
    return [permission() for permission in permission_classes]

以上示例中,get_permissions() 方法根据当前动作(self.action)来确定要应用的权限类。如果当前动作是 list,则使用 IsAuthenticated 权限类;否则,使用 IsAdminUser 权限类。最后,将权限类实例化并作为列表返回。

六、自定义actions

在 Django REST Framework 中,ViewSet 是一个组合了多个动作(actions)的视图类,提供常见的 CRUD(默认的 create/retrieve/update/destroy 操作创建、读取、更新、删除)操作。反射指的是通过反射机制自动识别视图集中定义的动作,并根据它们生成符合 RESTful 风格的 URL。

使用反射可以让你更加方便地管理视图集中的动作,并自动生成对应的 URL 配置。Django REST Framework 为我们提供了 @action 装饰器,使得在视图集中定义和命名动作变得非常容易。

以下是一个示例,演示如何在视图集中使用 @action 装饰器来定义自定义动作:

from rest_framework.decorators import action

class ProjectsViewSet(viewsets.ViewSet):
    # GET /projects/custom_action/
    @action(detail=False, methods=['get'])
    def custom_action(self, request):
        # 在这里执行自定义动作的逻辑
        return Response("Custom Action")

    # GET /projects/1/custom_action_detail/
    @action(detail=True, methods=['get'])
    def custom_action_detail(self, request, pk=None):
        # 获取特定项目对象
        project = self.get_object()
        # 在这里执行特定项目的自定义动作逻辑
        return Response(f"Custom Action for Project {project.id}")

    # ...

在上面的示例中,我们在 ProjectsViewSet 中定义了两个自定义动作:custom_actioncustom_action_detail

  • custom_action 是一个针对集合的动作,它不关联到特定的项目详情。可以通过发送 GET 请求到 /projects/custom_action/ 执行自定义动作。
  • custom_action_detail 是一个针对特定项目的动作,它关联到特定的项目详情。可以通过发送 GET 请求到 /projects/{id}/custom_action_detail/ 执行自定义动作。

使用 detail=False 参数,我们告诉 Django REST Framework 这是一个针对集合的动作;

使用 detail=True 参数,我们告诉它这是一个针对特定项目的动作。

在 URL 配置中,Django REST Framework 会自动识别并为我们生成包含这些自定义动作的 URL。因此,你无需手动编写这些 URL,只需在主路由配置中引入视图集,并让框架为你处理 URL 映射。

总之,使用反射ViewSet actions 可以方便地定义自定义动作,并自动生成相应的 URL 配置。

通过使用@action装饰器,您可以在ViewSet中定义和配置超出标准CRUD操作的额外操作。

@action装饰器默认会路由GET请求,但也可以通过设置methods参数接受其他HTTP方法。例如:

@action(detail=True, methods=['post', 'delete'])
def unset_password(self, request, pk=None):
   ...

该装饰器允许您覆盖任何视图集级别的配置,例如permission_classes、serializer_class、filter_backends等:

@action(detail=True, methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
   ...

6.1、http请求put方法、delete方法

例如,上述密码设置/取消方法可以合并为一个路由。请注意,附加映射不接受参数。

@action(detail=True, methods=['put'], name='Change Password')
def password(self, request, pk=None):
    """Update the user's password."""
    ...

@password.mapping.delete
def delete_password(self, request, pk=None):
    """Delete the user's password."""
    ...

在上面的示例中,我们定义了名为"Change Password"的额外操作,并将其映射到PUT方法。在方法体内,我们可以执行更新用户密码的逻辑。

同时,我们使用.mapping.delete装饰器将额外操作delete_password映射到DELETE方法。在该方法内,我们可以执行删除用户密码的逻辑。

通过这种方式,您可以为额外操作定义不同的HTTP方法,以满足您的需求。

八、获取操作的URL

如果您需要获取操作的URL,请使用.reverse_action()方法。这是reverse()方法的一个便利包装,它会自动传递视图的请求对象,并在url_name之前添加.basename属性。

请注意,basename是在ViewSet注册期间由路由器提供的。如果您没有使用路由器,则必须在.as_view()方法中提供basename参数。

使用前面一节的示例:

>>> view.reverse_action('set-password', args=['1'])
'http://localhost:8000/api/users/1/set_password'

另外,您还可以使用由@action装饰器设置的url_name属性。

>>> view.reverse_action(view.set_password.url_name, args=['1'])
'http://localhost:8000/api/users/1/set_password'

.reverse_action()方法的url_name参数应与@action装饰器的相同参数匹配。此外,该方法还可用于反转默认操作,例如list和create。

九、其他

生成迁移脚本:

python manage.py makemigrations

执行迁移:

python manage.py migrate

 手动在数据库中,插入数据,sql

INSERT tb_projects VALUES(null,'喵喵项目','张三','里斯','开发A','应用A','','2023-06-13 03:32:13.421713', '2023-06-13 03:32:13.421775');
INSERT tb_projects VALUES(null,'汪汪项目','张三','里斯','开发A','应用A','','2023-06-13 03:32:13.421713', '2023-06-13 03:32:13.421775');
INSERT tb_projects VALUES(null,'阿苗项目','张三','里斯','开发A','应用A','','2023-06-13 03:32:13.421713', '2023-06-13 03:32:13.421775');

 

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

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

相关文章

Git下载与安装(windows)

文章目录 Git 简介Git 下载Git 安装Git 环境变量配置 Git 简介 Git 是一种分布式版本控制系统&#xff0c;用于快速、高效地处理任何大小规模的项目。它是由 Linus Torvalds 在 2005 年开始开发的&#xff0c;Git 最初是为了管理 Linux 内核源代码而创建的。现在 Git 是一个广…

python脚本(Word转PDF格式小工具)

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QMessageBox from PyQt5.QtCore import Qt import sys import os from comtypes import client#文件转换脚本 class FileDropWidget(QWidget):def __init__(self):super().__init__()self.initUI()de…

IDEA+spring boot+mybatis+spring mvc+bootstrap+Mysql停车位管理系统源码

IDEAJavaSpring BootMyBatisshiroLayuiMysql停车位管理系统源码 一、系统介绍1.环境配置 二、系统展示1.登录2.注册3.个人信息4.修改密码5.我的订单6.我的留言7.查车位8.管理员登录9.公告列表10.车位列表11. 订单列表12. 积分排行13. 留言列表14.管理员列表15. 用户列表16.修改…

MySQL:整型类型的显示列宽

整型类型的显示列宽 1、概述2、显示宽度3、总结 1、概述 大家好&#xff0c;我是欧阳方超。 关于定义整型时括号中的数值&#xff0c;再补充一下。 2、显示宽度 定义整型类型&#xff0c;比如int(10)&#xff0c;这个括号中的值被称为展示宽度&#xff08;display width&…

Hive查询操作

Hive基本查询语法 基本使用规则 基本查询语句组成 select .. from ..join [tableName] on ..where ..group by ..having ..order by ..sort by ..limit .. union | union all ...执行顺序 第一步: FROM <left_table> 第二步: ON <join_condition> 第三步: <join…

python使用matplotlib库绘制数学函数

** 任务一&#xff1a;使用matplotlib绘制yx的曲线图 ** matplotlib是python的绘画库&#xff0c;它可以与NumPy一起使用&#xff0c;提供了一种轻量级的MatLab开源高效替代方案。它可以和图形工具包PyQt等工具 一起配合使用&#xff0c;能够完成日常科学计算中多种数学库图可…

RuoYi(分离版) 使用代码生成器添加子模块(idea版)

右键总文件夹&#xff0c;选择新模块添加新模块 新建的业务模块 新建的业务模块中添加若依通用模块工具 <dependencies><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-common</artifactId></dependency></depen…

窨井水位监测的重要性

窨井是排水管网的检查井&#xff0c;能够直观准确的反映城市排水管网的运行状态&#xff0c;在城市排水系统中扮演着重要的角色。窨井水位监测是指对城市下水道或雨水收集系统中的窨井水位进行实时或定期的监测和测量。 窨井水位监测的重要性 预防溢流&#xff1a;窨井水位监测…

Nacos 无缝支持 confd 配置管理

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Android Studio实现内容丰富的安卓物业管理平台

如需源码可以添加q-------3290510686&#xff0c;也有演示视频演示具体功能&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号102 1.开发环境 android stuido3.6 jak1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看公告…

调用接口异常的原因及解决方法

在进行接口调用时&#xff0c;调用有时会遇到各种异常情况&#xff0c;接口解决例如连接超时、异常因及返回值错误等。调用的原这些异常情况可能会导致程序无法正常运行&#xff0c;接口解决因此需要及时解决。异常因及本文将介绍。调用的原 一、接口解决连接超时 连接超时是异…

面试题-Spring 面试集

Spring 面试集 基于Spring Framework 4.x 总结的常见面试题&#xff0c;系统学习建议还是官方文档走起&#xff1a;https://spring.io/projects/spring-framework#learn 一、一般问题 开发中主要使用 Spring 的什么技术 ? IOC 容器管理各层的组件 使用 AOP 配置声明式事务 整…

Vue2+vue-cli使用Tailwind CSS

1.执行以下命令安装依赖 npm install tailwindcssnpm:tailwindcss/postcss7-compat tailwindcss/postcss7-compat postcss^7 autoprefixer^92.cmd执行命令npm i 下载项目所用到的依赖 npm i3.在项目根目录下创建一个 postcss.config.js 文件 module.exports {plugins: [requ…

fcpx插件:Kingluma Radiance(发光和光线过渡效果)

Kingluma Radiance是一款为Final Cut Pro X&#xff08;FCPX&#xff09;设计的插件&#xff0c;它提供了丰富的光效和发光效果&#xff0c;可用于增强视频的视觉效果。 Radiance插件为用户提供了多种发光效果和光晕效果&#xff0c;如光晕、镜头光晕、梦幻效果等。它具有直观的…

推荐信模版(英文)计算机专业

推荐信模版&#xff08;英文&#xff09;计算机专业 ✅ 内容已校对 润色 ©️ 文章来源&#xff1a;https://blog.csdn.net/IYXUAN&#xff0c;原创内容&#xff0c;转载请注明&#xff01; 推荐信&#xff08;一&#xff09; January 4, 2023 Dear Admissions Committe…

7.4黄金能否继续上行?今日行情如何发展

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周二(7月4日)亚市早盘&#xff0c;美元指数继续承压&#xff0c;目前略低于103关口;现货黄金保持在1923美元/盎司附近。由于悲观的美国数据未能支持美联储的鹰派倾向…

node获取文件夹下所有js文件的模块

创建 index.js const fs require(fs) const path require(path)const folderPath path.join(__dirname, api)console.log(目录路径&#xff1a;, folderPath)let moduleObj {}fs.readdirSync(folderPath).forEach((file) > {const filePath path.join(folderPath, file…

C语言指针基础

目录 前言 本期介绍内容&#xff1a; 一、指针是什么&#xff1f; 二、指针和指针类型 指针类型的意义&#xff1a; 三、野指针 3.1什么是野指针&#xff1f; 3.2野指针的成因 1.指针未初始化 2.指针越界访问 3.指针指向的那块空间已经释放&#xff08;还给操作系统了…

图像处理--边缘检测算子

算子推导过程 1、知识引入&#xff1a; 在一维连续数集上有函数f(x),我们可以通过求导获得该函数在任一点的斜率&#xff0c;根据导数的定义有&#xff1a; 在二维连续数集上有函数f(x,y),我们也可以通过求导获得该函数在x和y分量的偏导数&#xff0c;根据定义有&#xff1a; …

更改VS code Jupyter 插件的默认快捷键

更改vscode 中Jupyter插件的默认快捷键&#xff0c;解放插入空行的系统快捷键 替换Jupyter默认快捷键 更改vscode 中Jupyter插件的默认快捷键&#xff0c;解放插入空行的系统快捷键打开keyboard shortcuts 设置方法一方法二 更换快捷键 end Jupyter 插件很好的在VS code中集成了…