DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射)

news2025/2/8 13:19:42

DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射)

目录

  • DRF视图组件(2个视图基类、5个视图扩展类、9个视图子类、视图集和路由映射)
    • 2个视图基类
    • mixins的5个视图扩展类
    • generics的9个视图子类
    • 视图集
    • 自定制返回格式
    • 自动生成路由(SimpleRouter)
    • action装饰器

2个视图基类

APIView写法:

from rest_framework.views import APIView


class publish(APIView):
    def get(self, request):
        publish_obj = models.Publish.objects.all()
        serializer = PublishSerializer(instance=publish_obj, many=True)
        return Response({'code': '200', 'msg': '查询成功', 'result': serializer.data})

    def post(self, request):
        serializer = PublishSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': '200', 'msg': '添加成功', 'result': serializer.data})
        else:
            return Response({'code': '900', 'msg': serializer.errors})


class publish_detail(APIView):
    def get(self, request, u_id):
        publish_obj = models.Publish.objects.get(id=u_id)
        serializer = PublishSerializer(instance=publish_obj)
        return Response({'code': '200', 'msg': '查询成功', 'result': serializer.data})

    def delete(self, request, u_id):
        pass

    def put(self, request, u_id):
        publish_obj = models.Author.objects.filter(pk=u_id).first()
        # 改对象必须传data和instance
        serializer = PublishSerializer(instance=publish_obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': '200', 'msg': "修改成功", 'result': serializer.data})
        else:
            return Response({'code': '201', 'msg': serializer.errors})

GenericAPIView类改写:

from rest_framework.generics import GenericAPIView


class publish(GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request):
        publish_obj = self.get_queryset()
        serializer = self.get_serializer(instance=publish_obj, many=True)
        return Response({'code': '200', 'msg': '查询成功', 'result': serializer.data})

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': '200', 'msg': '添加成功', 'result': serializer.data})
        else:
            return Response({'code': '900', 'msg': serializer.errors})


class publish_detail(GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, pk):
        publish_obj = self.get_object()
        serializer = self.get_serializer(instance=publish_obj)
        return Response({'code': '200', 'msg': '查询成功', 'result': serializer.data})

    def delete(self, request, pk):
        self.get_object().delete()
        return Response({'code': '200', 'msg': '删除成功'})

    def put(self, request, pk):
        publish_obj = self.get_object()
        # 改对象必须传data和instance
        serializer = self.get_serializer(instance=publish_obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': '200', 'msg': "修改成功", 'result': serializer.data})
        else:
            return Response({'code': '201', 'msg': serializer.errors})
  • queryset = models.Publish.objects.all():查询所有数据
  • serializer_class = PublishSerializer:获取序列化类(本文未展示)
  • publish_obj = self.get_queryset():获取所有数据
  • serializer = self.get_serializer(instance=publish_obj, many=True):使用定义好的序列化类
  • self.get_object():这里不需要传入pk,直接用它定义好的方法,但是它默认识别的只有pk,取其他名会报错

mixins的5个视图扩展类

  • CreateModelMixin:新增

  • ListModelMixin:查询所有

  • DestroyModelMixin:删除单条

  • UpdateModelMixin:修改单条

  • RetrieveModelMixin:查询单条

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    UpdateModelMixin
    
    
class publish(GenericAPIView, CreateModelMixin, ListModelMixin):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request):
        res = super().list(request)
        return Response({'code': '200', 'msg': '查询成功', 'result': res.data})

    def post(self, request):
        res = super().create(request)
        print(type(res))
        return Response({'code': '200', 'msg': '添加成功', 'result': res.data})


class publish_detail(GenericAPIView, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, *args, **kwargs):
        res = super().retrieve(request, *args, **kwargs)
        return Response({'code': '200', 'msg': '查询成功', 'result': res.data})

    def delete(self, request, *args, **kwargs):
        res = super().destroy(request, *args, **kwargs)
        return Response({'code': '200', 'msg': '删除成功'})

    def put(self, request, *args, **kwargs):
        res = super().update(request, *args, **kwargs)
        return Response({'code': '200', 'msg': "修改成功", 'result': res.data})
  • res = super().list(request):调用ListModelMixin类中的list方法可以省去查询数据和序列化的书写,下面的都一样
  • 注:res是一个 Response 实例,而不是一个序列化器实例,因此对返回值调用 .is_valid()之类的方法会报AttributeError

generics的9个视图子类

  • CreateAPIView:新增
  • DestroyAPIView:删除
  • ListAPIView:查询所有
  • ListCreateAPIView:查询所有和新增的合并
  • RetrieveAPIView:查询单个
  • RetrieveDestroyAPIView:查询单个和删除的合并
  • RetrieveUpdateAPIView:查询单个和修改的合并
  • RetrieveUpdateDestroyAPIView:查询单个、修改和删除的合并
  • UpdateAPIView:修改
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
    
    
class publish(ListCreateAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

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

视图集

# views.py
from rest_framework.viewsets import ModelViewSet

class publish(ModelViewSet):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer
# urls.py
from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('publish/', views.publish.as_view({'get': 'list', 'post': 'create'})),
    path('publish/<str:pk>/', views.publish.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
  • 此时就不需要再分一个publish_detail类了,ModelviewSet已经帮你把五个接口全部写好了,只需在路由层添加映射
  • 'get': 'list':表示遇到get请求时执行list方法,其他的也是

自定制返回格式

  • 不管是视图子类还是视图集,需要自定制返回字段时只需重写所需方法就行

  • 例如我要自定制查询所有的返回值就重写list:

class publish(ListCreateAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializer

    def list(self, request, *args, **kwargs):
        res = super().list(request, *args, **kwargs)
        res.data = {"code": 200, "msg": "查询成功", "result": res.data}
        return Response(res.data)
  • res.data默认返回的是一个包含多个字典的列表

自动生成路由(SimpleRouter)

# urls.py
from rest_framework.routers import SimpleRouter
from app import views

# 实例对象
router = SimpleRouter()
# 将publish类注册,最左边的publish为浏览器输入的路由,最右边的publish是别名
router.register('publish', views.publish, 'publish')

urlpatterns = [
]
# 将注册好的路由添加进urlpatterns

现在得到的路由其实就是http://127.0.0.1:8000/publish/,调用的视图类是publish,并且pk它也会自动帮你写好

与SimpleRouter类似的还有DefaultRouter,他俩基本用法完全一致,唯一不同的是DefaultRouter会返回一个根路径

  • SimpleRouter
image-20240415205837533
  • DefaultRouter
image-20240415205916923

点进Api Root后可以看到它返回了一个根路径

{
    "publish": "http://127.0.0.1:8000/publish/"
}

action装饰器

SimpleRouter自动生成路由后有一个弊端就是当绑定的类中没有get\path这种方法名时会注册失败

例如我现在有一个login方法,我想让他接受get请求实现查询单个的功能要,只需在上面价加个action装饰器

# views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action

class publish(ModelViewSet):
    
    @action(methods=['GET'], detail=False)
    def login(self, request)

action参数:(methods=None, detail=None, url_path=None, url_name=None, **kwargs):

  • methods:包含被允许的请求方法
  • detail:指定是否需要提供对象的详细信息
  • url_path:指定自定义的 URL 路径
  • url_name:指定自定义的 URL 名称

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

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

相关文章

非监督学习的模型为条件概率分布P(z|x)和p(x|z)的区别

在无监督学习中&#xff0c;假设X是输入空间&#xff0c;Z是输出的隐式结构空间&#xff0c;要学习的模型非概率模型情况可以表示为函数zg(x)&#xff0c;概率模型情况下表示为条件概率分布P&#xff08;z|x&#xff09;或p(x∣z)&#xff0c;它们 都可以用来描述数据中的潜在结…

[ROS 系列学习教程] 建模与仿真 - URDF 语法介绍

ROS 系列学习教程(总目录) 本文目录 一、robot标签二、link标签三、joint标签 URDF文件中使用XML格式描述的机器人模型&#xff0c;下面介绍URDF的XML标签。 一、robot标签 机器人描述文件中的根元素必须是robot&#xff0c;所有其他元素必须封装在其中。 属性 name&#x…

JetBrains Rider 2024.1 发布 - 快速且强大的跨平台 .NET IDE

JetBrains Rider 2024.1 发布 - 快速且强大的跨平台 .NET IDE 请访问原文链接&#xff1a;JetBrains Rider 2024.1 (macOS, Linux, Windows) - 快速且强大的跨平台 .NET IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Jet…

jpa使用Querydsl需要规避的一些坑

在使用Spring Data JPA时&#xff0c;通常会使用Querydsl来构建类型安全的查询。在Querydsl中&#xff0c;为了区分实体类与Querydsl查询类&#xff0c;习惯上会给查询类的前缀添加一个"Q"&#xff0c;表示该类是一个查询类。这样做可以有效地避免实体类与查询类之间…

数据结构和算法(哈希表和图(A*算法精讲))

一 、哈希表 1.1 哈希表原理精讲 哈希表-散列表&#xff0c;它是基于快速存取的角度设计的&#xff0c;也是一种典型的“空间换时间”的做法 键(key)&#xff1a; 组员的编号如&#xff0c;1、5、19。。。 值(value)&#xff1a; 组员的其它信息&#xff08;包含性别、年龄和…

pyqt实现星三角减压启动

这个对于plc上实现是非常容易得。它本来就是逻辑控制器&#xff0c;如果用代码实现它&#xff0c;该怎么做呢&#xff1f;这个实现起来看似简单&#xff0c;实则是有不少坑的&#xff08;大神除外&#xff09;。我一直想用类来封装&#xff0c;让它继承QObject,为啥非要继承QOb…

电信网络如何异地共享文件?

电信异地共享文件是指在不同地区的电信网络下&#xff0c;通过使用特定技术实现文件的共享和传输。在传统的网络环境中&#xff0c;由于网络限制和复杂的网络设置&#xff0c;实现跨地区的文件共享是一个具有挑战性的任务。随着技术的不断进步&#xff0c;现在可以利用电信异地…

Spring Boot | SpringBoot对 “SpringMVC“的 “整合支持“、SpringMVC“功能拓展实现“

目录: SpringMVC 的 “整合支持” ( 引入"Web依赖启动器"&#xff0c;几乎可以在无任何额外的配置的情况下进行"Web开发")1.SpringMVC "自动配置" 介绍 ( 引入Web依赖启动器"后&#xff0c;SpringBoot会自动进行一些“自动配置”&#xff0…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《应用图论建模输电网的电力现货市场出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【cuda\cudnn安装教程】以及环境变量设置(以cuda11.8为例)

【cuda\cudnn安装教程】以cuda11.8为例 cuda11.8安装 安装的时候一切都是按默认安装就好&#xff0c;地址也是默认路径 cudnn安装 下载需要登陆&#xff0c;按要求注册就好 将cudnn压缩包中的内容复制到cuda的安装路径中&#xff0c;进行替换&#xff0c;如下图 验证cuda是否…

可视化报表Superset

文章目录 一、Superset入门与安装1、Superset概述2、安装Python环境2.1 安装Miniconda2.2 创建Python3.7环境 3、Superset部署3.1 安装Superset3.2 启动Supterset3.3 superset启停脚本 4、docker部署 二、Superset使用与实战1、对接MySQL数据源2、制作仪表盘与图表 一、Superse…

【Canvas与艺术】绘制斜置黄色三角biohazard标志

【关键点】 径向渐变色和文字按角度偏转。 【成果图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>使用Html5/Canvas绘制…

2024蓝桥A组E题

成绩统计 问题描述格式输入格式输出样例输入样例输出评测用例规模与约定解析参考程序难度等级 问题描述 题目有问题方差定义那加平方&#xff08;vi-v&#xff09; 格式输入 输入的第一行包含三个正整数n,k,T &#xff0c;相邻整数之间使用一个空格分隔。 第二行包含n个正整数…

使用go和消息队列优化投票功能

文章目录 1、优化方案与主要实现代码1.1、原系统的技术架构1.2、新系统的技术架构1.3、查看和投票接口实现1.4、数据入库MySQL协程实现1.5、路由配置1.6、启动程序入口实现 2、压测结果2.1、设置Jmeter线程组2.2、Jmeter聚合报告结果&#xff0c;支持11240/秒吞吐量2.3、Jmeter…

2022年电赛F题23年电赛D题-信号调制度测量装置说明中提到带通采样定律。

2022年电赛F题-信号调制度测量装置说明中提到带通采样定律。 23年电赛D题十分相似&#xff0c;但是22年载波达到了10M&#xff0c;根据奈奎斯特采样定理&#xff0c;我们知道想要分析出频谱不混叠的频谱图&#xff0c;采样率必须大于最大谐波的二倍。那么就意味着AD采样率要大…

2023年图灵奖揭晓,你怎么看?

Avi Wigderson——理论计算机科学的先锋&#xff0c;荣获2023年图灵奖 在科技界&#xff0c;图灵奖堪称与诺贝尔奖齐名的崇高荣誉&#xff0c;它每年授予对计算机行业的贡献达到重大突破的个人或团队。今年&#xff0c;这一声誉卓著的奖项被授予了普林斯顿大学的数学教授 Avi …

【攻防世界】lottery

弱比较代码审计 本题已提供源码&#xff0c;如果没提供&#xff0c;输入/robots.txt&#xff0c;发现/.git function buy($req){require_registered();require_min_money(2);$money $_SESSION[money];//接受用户原有money$numbers $req[numbers];//接受输入的数字$win_num…

面试八股——JVM★

类加载 类加载器的定义 类加载器的类别 类装载的执行过程 类的装载过程&#xff1a; 加载&#xff1a; 验证&#xff1a; 准备&#xff1a; 这里设置初始值并不是传统意义的设置初始值&#xff08;那个过程在初始化阶段&#xff09;。 解析&#xff1a; 初始化&#xff1a; …

树莓派安装Nginx服务结合内网穿透实现无公网IP远程访问

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

【BlueDroid】Android BLE 蓝牙开发入门

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【精讲蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待&#…