Django REST framework--类视图

news2024/10/6 8:28:09

Django REST framework--类视图

    • 基于类的视图
      • APIView类视图
      • generics通用类视图
      • 视图集
        • DRF框架路由

基于类的视图

项目开发中要不断思考如何让代码保持高内聚,低耦合,因此优化代码的道路上一直都不停歇。目前开发的视图是基于函数形式的,特点是灵活,缺点是功能冗余性大,面对常见的增删改查往往要写重复的代码。

REST框架可以用基于类的视图来优化代码结构

APIView类视图

用类重写视图,继承REST框架的APIView类

sqtp应用app目录下的views.py文件下将request_listrequest_detail两个视图函数修改为类视图

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt    # 跨站攻击防护,接口白名单处理
from rest_framework import status
from rest_framework.parsers import JSONParser       # 序列化
from rest_framework.response import Response

from sqtp.models import Request     # 模型
from sqtp.serializers import RequestSerializer      # 自定义的序列化类
from rest_framework.decorators import api_view
from rest_framework.views import APIView  # 继承APIView类视图

# 改写 request_list 视图方法
class RequestList(APIView):
    '''
    查询所有数据和新增单个数据的功能
    '''
    def get(self,request,format=None):
        # 获取序列化器--针对当前数据模型的所有数据
        serializer = RequestSerializer(Request.objects.all(), many=True)
        return Response(serializer.data)  # 使用DRF框架的响应对象,自动分配返回格式

    # 处理新增请求
    def post(self,request,format=None):
        # 构建序列化器,反序列化,将request.data数据恢复成正常的对象实例
        serializer = RequestSerializer(data=request.data)
        # 校验数据是否合法
        if serializer.is_valid():
            serializer.save()
            # 新增成功返回新增数据状态码201
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        # 新增失败返回错误信息400,请求数据有问题
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# 改写 request_detail 视图方法
class RequestDetail(APIView):

    # 覆盖父类的get_object方法实现
    def get_object(self,_id):
        try:
            return Request.objects.get(id=_id)
        except Exception:
            return Response(status=status.HTTP_404_NOT_FOUND)  # 返回错误状态码

    def get(self,request,_id,format=None):
        # 序列化,将数据对象转化为json格式
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj,Response):
            return req_boj
        serializer = RequestSerializer(req_boj)
        return Response(data=serializer.data)

    def put(self,request,_id,format=None):
        # 采用序列化器实现修改,这里与查询不同的是,还需要把待修改的数据放到序列化器里进行覆盖
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj, Response):
            return req_boj
        serializer = RequestSerializer(req_boj, data=request.data)
        # 判断data中的数据是否符合要求
        if serializer.is_valid():
            # 若符合要求则进行保存操作
            serializer.save()
            # 将修改成功的状态码返回
            return Response(serializer.data, status=status.HTTP_200_OK)
        # 修改失败返回错误信息400,修改传递的数据有问题
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self,request,_id,format=None):
        req_boj = self.get_object(_id)
        # 如果是异常响应,直接返回
        if isinstance(req_boj, Response):
            return req_boj
        req_boj.delete()  # 获取数据后进行删除
        # 将删除成功的状态码返回
        return Response(status=status.HTTP_204_NO_CONTENT)

修改sqtp应用app目录下的urls.py文件

from django.urls import path
from sqtp import views as sqtp_view
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
  path('requests/',sqtp_view.RequestList.as_view()),  # 视图类需要调用 as_view转化
  path('requests/<int:_id>',sqtp_view.RequestDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns) # 重写url

行命令python manage.py runserver 0.0.0.0:8888启动项目,在浏览器中输入http://127.0.0.1:8888/requests/,可以发现页面返回内容与视图函数,是一样的

generics通用类视图

使用类视图的一个好处就是可以复用相同的功能,只需传入指定的参数即可。在上面的案例中,增删改查的逻辑行为都是确定的。

REST框架为我们封装好了逻辑,可以用更少的代码来封装视图,比如采用generics模块的通用视图:通过generics.ListCreateAPIViewm 实现列出所有和新增;通过generics.RetrieveUpdateDestroyAPIView获取单个、更新和删除功能

sqtp应用app目录下的views.py文件下将request_listrequest_detail两个视图函数修改为generics通用类视图

from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView   # 继承generics通用类视图

# 改写 request_list 视图方法
class RequestList(ListCreateAPIView):
    queryset = Request.objects.all()    # 数据的查询集
    serializer_class = RequestSerializer


# 改写 request_detail 视图方法
class RequestDetail(RetrieveUpdateDestroyAPIView):
    queryset = Request.objects.all()  # 数据的查询集
    serializer_class = RequestSerializer

由于是 RequestDetail视图类是继承RetrieveUpdateDestroyAPIView类,所以参数id的名称要为pk,这是底层代码GenericAPIView类中的要求限制lookup_field = 'pk'

否则,浏览器中输入http://127.0.0.1:8888/requests/43,就会产生报错,提示修改url配置

AssertionError: Expected view RequestDetail to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.

修改sqtp应用app目录下的urls.py文件,将requests/<int:_id>修改为requests/<int:pk>

from django.urls import path
from sqtp import views as sqtp_view
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
  path('requests/',sqtp_view.RequestList.as_view()),  # 视图类需要调用 as_view转化
  path('requests/<int:pk>',sqtp_view.RequestDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns) # 重写url

重启服务,测试增删改查,依然OK!

可以发现,数据详情的编辑页面还支持按字段进行编辑,这是通用类视图提供的效果。

在这里插入图片描述

视图集

通过使用generics通用类视图,代码量已经减少到了不到10行,优化后的视图代码依然存在重复的部分,这部分的代码依旧可以继续优化,用ViewSet(视图集)代替View类重构视图

sqtp应用app目录下的views.py文件下将RequestLisRequestDetail两个视图类修改一个

from rest_framework import viewsets

class RequestViewSet(viewsets.ModelViewSet):
    queryset = Request.objects.all()  # 数据的查询集
    serializer_class = RequestSerializer

使用REST ViewSets 的抽象后,开发人员可以集中精力对API的状态和交互进行建模,并根据常规约定自动处理URL构造。

ViewSet 类与 View 类几乎相同,不同之处在于它们提供诸如 read 或 update 之类的操作,而不是 get 或 put 等方法处理程序。

一个 ViewSet 类只绑定到一组方法处理程序,当它被实例化成一组视图的时候,通常通过使用一个 Router 类来代替自己定义复杂的URL。

DRF框架路由

因为使用的是 ViewSet 类而不是 View 类,所以连常规的URL设计都可以偷懒了。利用rest框架 的router,可以自动生成路由列表。

修改sqtp应用app目录下的urls.py文件

from django.urls import path,include
from sqtp import views as sqtp_view
# 使用rest框架自带的路由器生成路由列表
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'requests',sqtp_view.RequestViewSet)

urlpatterns = [
    path('',include(router.urls))
]

router的作用是根据注册的路由前缀,帮助你自动生成诸如此类的路由列表,根据正则匹配参数、后缀等内容

^requests/$ [name='request-list']
^requests\.(?P<format>[a-z0-9]+)/?$ [name='request-list']
^requests/(?P<pk>[^/.]+)/$ [name='request-detail']
^requests/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='request-detail']

重启服务,测试增删改查,依然OK!

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

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

相关文章

Effective Objective-C 2.0学习记录(四)

学习记录15.用前缀避免命名空间冲突16.提供“全能初始化方法”17.实现description方法debugDescription&#xff1a;18.尽量使用不可变对象19.使用清晰而协调的命名方式类与协议的命名20.为私有方法名加前缀21.理解OC错误模型22.理解NSCopying协议深拷贝和浅拷贝15.用前缀避免命…

【1-神经网络计算】北京大学TensorFlow2.0

课程地址&#xff1a;【北京大学】Tensorflow2.0_哔哩哔哩_bilibiliPython3.7和TensorFlow2.1六讲&#xff1a;神经网络计算&#xff1a;神经网络的计算过程&#xff0c;搭建第一个神经网络模型神经网络优化&#xff1a;神经网络的优化方法&#xff0c;掌握学习率、激活函数、损…

ArcGIS基础实验操作100例--实验99三维爆炸分析

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 空间分析篇--实验99 三维爆炸分析 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

Open3D ICP精配准(使用鲁棒性核函数,Python版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 标准的ICP算法(点到平面)是使得下面这个目标函数最小化: 其中 p 、 q p、q p、q是相对应的匹配点,

RocketMQ5.0.0路由中心NameServer

一、NameServer概览NameServer是RocketMQ的注册中心&#xff0c;是消息存储Broker、生产者、消费者沟通的桥梁。NameServer集群之间是相互独立的&#xff0c;Broker启动时向所有NameServer注册中心注册。通过DLedger构建NameServer集群&#xff0c;实现如主从切换等功能。启动N…

【笔记】大话设计模式24-28

【笔记】大话设计模式24-28 文章目录【笔记】大话设计模式24-2824 职责链模式24.1 Example24.2 定义24.3 Show me the code24.4 总结25 中介者模式25.1 Example25.2 定义25.3 Show me the code25.4 总结26 享元模式26.1 Example26.2 定义26.3 Show me the code26.4 总结27 解释…

aws s3 参与s3game寻找宝藏游戏挑战学习s3对象存储

参考资料 Pirates S3game workshop http://s3game-level1.s3-website.us-east-2.amazonaws.com/level1.html https://blog.benclmnt.com/notes/s3-game/ https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html 强烈推荐这种寓教于乐的方式学…

【ROS2 入门】ROS 2 actions 概述

大家好&#xff0c;我是虎哥&#xff0c;从今天开始&#xff0c;我将花一段时间&#xff0c;开始将自己从ROS1切换到ROS2&#xff0c;在上一篇中&#xff0c;我们一起了解ROS 2中Parameters&#xff0c; 这一篇&#xff0c;我们主要会围绕ROS中另外一个重要的概念“Actions ”来…

Linux 系统调用的实现(x86_64)

目录 1、系统调用的定义 1.1 SYSCALL_METADATA宏 1.2 __SYSCALL_DEFINEx定义 2、系统调用表-sys_call_table数组的定义 3、用户态系统调用流程 kernel 5.10 1、系统调用的定义 系统调用的定义我们其实都不陌生&#xff0c;类似这样的函数SYSCALL_DEFINE0&#xff0c; SYSC…

C语言常见错误汇总

1 数组遍历时使用sizeof(a) 任务&#xff1a;有个数组&#xff0c;找出第二大的数&#xff0c;并且打印出来&#xff08;使用*操作数组元素个数&#xff0c;不要使用[]&#xff09; #include<stdio.h> int main01() {int a[] { 100,100,100,234,123,500,32,68,41,99,1…

code.org免费的少儿编程入门平台

现在市面上的少儿编程课&#xff0c;都是先花9.9就能体验几节课&#xff0c;然后要花几千块才能继续学习后面的课程。这些钱大可不必花。 现在给大家推荐一个免费的网站&#xff0c;code.org&#xff0c;它是一个非营利组织创办的网站&#xff0c;目标是让每个学生都能像生物、…

高并发系统设计 --多级缓存

为了提高系统的性能&#xff0c;一般会引入“缓存机制”&#xff0c;将部分热点数据存入缓存中&#xff0c;用空间换取时间&#xff0c;以达到快速响应的目的。 我们对缓存的认知停留在redis&#xff0c;但其实缓存远远不是只有redis的&#xff0c;从客户端发起请求开始&#…

MySQL整体使用》导入数据、约束、多表查询、事务、变量类型、资源占用

我发的MySQL相关内容&#xff1a; C#基础知识体系框架图&#xff0c;及起对应我发过的博客 linux安装mysql8配置使用&#xff0c;并解决常见问题 MySQL常用命令&#xff08;DQL&#xff09; 执行脚本命令&#xff0c;本地生成SQL文件后在服务器执行 // 进入mysql命令控制 m…

svg绘(viewBox viewport preserveAspectRatio)代替png图片等

当我们的代码中需要一个小图标的时候没必要去iconfont进行下载图标使用 要是下载的png格式那么容量还很大 远不如svg 直接自己代码写 记住svg的坐标朝向和数学坐标轴不一样 实现下图添加的小图标 <svg width"20px" height"20px" style"border: …

2023java面试之Zookeeper基础

一、说说 Zookeeper 是什么&#xff1f;直译&#xff1a;从名字上直译就是动物管理员&#xff0c;动物指的是 Hadoop 一类的分布式软件&#xff0c;管理员三个字体现了 ZooKeeper 的特点&#xff1a;维护、协调、管理、监控。简述&#xff1a;有些软件你想做成集群或者分布式&a…

冯诺依曼体系结构

冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成&#xff1a; 输入单元&#xff1a;包括键盘, 鼠…

netbeans中配置maven

deploy-发布到远程maven库本节默认maven库为nexusnetbeans中按ctrl1&#xff0c;打开Project窗口&#xff1b;在Project窗口中找到相关的project或module,在项目名上点击鼠标右键&#xff1b;在弹出菜单中找到菜单“Run Maven”的子菜单“Goals”&#xff0c;并点击&#xff0c…

PCB封装创建(IC类+USB)

目录 一&#xff1a;IC类 封装原理图 规格参数选最大。创建过程 1.放置焊盘 2.我们需要八个上图焊盘&#xff0c;可以用特殊粘贴 3.丝印层设置 封装向导 右击0805R&#xff0c;选择footprint 输入焊盘尺寸 二&#xff1a;USB封装 原理图 创建过程 1.放置焊盘&#x…

SSM 03_SpringMVC REST风格 Postman SSM整合 拦截器

01-SpringMVC简介SpringMVC是隶属于Spring框架的一部分&#xff0c;主要是用来进行Web开发&#xff0c;是对Servlet进行了封装。SpringMVC是处于Web层的框架&#xff0c;所以其主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端&#xff0c;所…

元宇宙时代业务扩张,专精特新小巨人找到了增长“神器”

进入2023年&#xff0c;元宇宙时代正扑面而来。自从脸书公司更名为Meta以来&#xff0c;元宇宙就在全球迅速走红。《福布斯》认为&#xff0c;2030年全球元宇宙的市场规模有望高达5万亿美元。更为重要的是&#xff0c;元宇宙正在成为数实融合的新界面、未来商业的新型基础设施。…