Django一分钟:DRF ViewSet烹饪指南,创建好用的视图集
本文将介绍django视图集的内部实现,并带你重写部分代码自己组装强大且趁手的视图集,以满足自定义的业务需求,避免编写大量重复代码。
一、基础知识
Django Rest framework框架允许你将一组相关视图的逻辑组合到一个类中,也就是我们所谓的视图集ViewSet。
与APIView相比,ViewSet更加抽象,更难理解。APIView的使用方法非常直观,需要你提供诸如.get()或.post()之类的处理方法,并由其自动将请求分发到对应的方法上。ViewSet则不同,它要求你提供诸如.list()或.create()这类操作方法,在实现了这些方法之后,使用.as_view()方法请操作方法映射到不同的处理方法上,比如list->get、destroy->delete。
一个简单的示例
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Responseclass UserViewSet(viewsets.ViewSet):"""一个简单的视图集,实现获取用户列表和查询单个用户的功能"""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)
在很多普通业务中,增删改查的操作是相同的,比如请求数据列表的操作,无非是三步:数据库获取查询集->序列化->返回响应。drf预制了这些重复的工作,将通用的方法封装进了ModelViewSet,借助ModelViewSet我们可以非常轻松的完成增删改查等工作(对应APIView就是ModelAPIView):
class AccountViewSet(viewsets.ModelViewSet):"""只需要指定查询集和序列化器即可"""queryset = Account.objects.all()serializer_class = AccountSerializerpermission_classes = [IsAccountAdminOrReadOnly]
ModelViewSet本身不提供这些通用的list或create之类的方法,而是由一些列Mixin类来实现,ModelViewSet负责把它们组合起来:
class ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet): pass
就以CreateModelMixin为例,CreateModelMixin为我们提供了一个通用的和符合标准的create()方法,其过程也就是获取查询集->序列化->返回,没有特殊需求我们的视图集继承它就能获取预制的create方法,不需要再自己实现:
class CreateModelMixin:"""Create a model instance."""def create(self, request, *args, **kwargs):serializer = self.get_serializer(data=request.data)serializer.is_valid(raise_exception=True)self.perform_create(serializer)headers = self.get_success_headers(serializer.data)return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)def perform_create(self, serializer):serializer.save()def get_success_headers(self, data):try:return {'Location': str(data[api_settings.URL_FIELD_NAME])}except (TypeError, KeyError):return {}
细心观察在CreateModelMixin中我们获取序列化器的方法是get_serializer,此外一些其它的Minxin类中,你可能发现其获取查询集的方法是get_queryset或者filter_queryset,还有诸如paginate_queryset这样的方法,一个典型的示例就是ListModelMixin:
class ListModelMixin:"""List a queryset."""def list(self, request, *args, **kwargs):queryset = self.filter_queryset(self.get_queryset())page = self.paginate_queryset(queryset)if page is not None:serializer = self.get_serializer(page, many=True)return self.get_paginated_response(serializer.data)serializer = self.get_serializer(queryset, many=True)return Response(serializer.data)
这些方法并非凭空而来而是由GenericViewSet类来提供,准确说是它的父类GenericAPIView:
class GenericViewSet(ViewSetMixin, generics.GenericAPIView): pass
GenericViewSet继承GenericAPIView为各种Mixin提供统一的获取查询集、序列化器、分页、授权等等接口。
class GenericAPIView(views.APIView):...queryset = Noneserializer_class = None...def get_queryset(self):...def get_object(self):...def get_serializer(self, *args, **kwargs):...def get_serializer_class(self):...def get_serializer_context(self):...def filter_queryset(self, queryset):...def paginator(self):...def paginate_queryset(self, queryset):...def get_paginated_response(self, data):...
二、灵活自定义
drf预制的Mixin足够标准和通用,但如果我们的业务中有特殊需求,我们就需要对drf预制的Mixin重新烹饪,实际操作并不困难,接下来我们通过几个具体的场景来实际体会一下。
自定义响应格式
假如我想让视图集返回的响应遵循如下格式:
{"status": "ok","code": 200,"messages": [],"result": {"user": {"id": 123,"name": "shazow"}}
}
我们可以先实现一个自定义的响应类来替换掉Mixin中使用的响应类。
import json
from rest_framework.response import Responseclass Rep(Response):"""struct json response"""def __init__(self, result=None, message=None, status=None, code=None, **kwargs):if message is None:message = []data = {"status": status,"code": code,"message": message,"result": result}super().__init__(data, code, **kwargs)@staticmethoddef ok(result=None, message=None, code=None, **kwargs):return Rep(result=result, message=message, status="ok", code=code, **kwargs)@staticmethoddef err(result=None, message=None, code=None, **kwargs):return Rep(result=result, message=message, status="err", code=code, **kwargs)
以RetrieveModelMixin为例,你可以继承并重写retrieve,也可以干脆复制一份到自己的项目中,再修改retrieve方法,我们这里选择复制一份到自己的项目中。为了和原来的RetrieveModelMixin做区分,且将其命名为XRetrieveModelMixin:
class XRetrieveModelMixin:"""Retrieve a model instance."""# 使用我们自己的Rep响应类替换了Response响应类def retrieve(self, request, *args, **kwargs):try:instance = self.get_object()except Http404:return Rep.err(None, ["查询数据不存在"], status.HTTP_404_NOT_FOUND)serializer = self.get_serializer(instance)return Rep.ok(serializer.data, None, code=status.HTTP_200_OK)# 对比原来的
# class RetrieveModelMixin:
# """
# Retrieve a model instance.
# """
# def retrieve(self, request, *args, **kwargs):
# instance = self.get_object()
# serializer = self.get_serializer(instance)
# return Response(serializer.data)
自动记录创建和更新数据的用户
细心观察drf的Minxin类并不是将全部分逻辑写在一个create方法或者update方法中,实际上它把实现功能的代码拆分到了多个函数中。
以CreateModelMixin类为例,你可以看到create的方法由perform_create方法和get_success_headers组合而来:
class CreateModelMixin:"""Create a model instance."""def create(self, request, *args, **kwargs):serializer = self.get_serializer(data=request.data)serializer.is_valid(raise_exception=True)self.perform_create(serializer)headers = self.get_success_headers(serializer.data)return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)def perform_create(self, serializer):serializer.save()def get_success_headers(self, data):try:return {'Location': str(data[api_settings.URL_FIELD_NAME])}except (TypeError, KeyError):return {}
这样非常有利于我们进行重写,假如我们想对serializer.save()的过程做些修改,比如记录创建用户,我们就可以通过重写perform_create来实现:
class TrackerModelViewSet(ModelViewSet):def perform_create(self, serializer):serializer.save(created_by=self.request.user)# 记录更新操作的用户;perform_update来自UpdateModelMixindef perform_update(self, serializer):serializer.save(updated_by=self.request.user)
三、总结
学习drf是如何预制Mixin的,我们可以预制自己的Mixin类和视图集,运用得当我们可以打造属于自己的趁手工具以从大量重复工作中解脱。
相关文章:
Django一分钟:DRF ViewSet烹饪指南,创建好用的视图集
本文将介绍django视图集的内部实现,并带你重写部分代码自己组装强大且趁手的视图集,以满足自定义的业务需求,避免编写大量重复代码。 一、基础知识 Django Rest framework框架允许你将一组相关视图的逻辑组合到一个类中,也就是我…...
SEO友好的wordpress模板 应该具体哪些特征
在数字营销的时代,搜索引擎优化(SEO)对于任何网站来说都是至关重要的。WordPress作为全球最受欢迎的内容管理系统之一,提供了大量的模板(也称为主题)供用户选择。一个SEO友好的WordPress模板不仅可以帮助您的网站在搜索引擎中获得更好的排名,…...
1.MySQL存储过程基础(1/10)
引言 数据库管理系统(Database Management System, DBMS)是现代信息技术中不可或缺的一部分。它提供了一种系统化的方法来创建、检索、更新和管理数据。DBMS的重要性体现在以下几个方面: 数据组织:DBMS 允许数据以结构化的方式存…...
linux中使用docker命令时提示权限不足
问题:成功安装docker后,使用docker相关命令时提示权限不足(permission denied) liubailiubai:~$ docker version Client: Version: 24.0.5 API version: 1.43 Go version: go1.20.14 Git commit: ced0996 Built: Tue Jun 25 22:3…...
Lucene最新最全面试题及参考答案
目录 Lucene主要功能及应用场景 Lucene 的索引结构是怎样的? Lucene 中的 Segment 是如何工作的? 如何在 Lucene 中实现文档的增删改查? Lucene 中存储的数据类型有哪些? 解释一下 Lucene 的索引过程。 Lucene 的搜索过程包含哪些步骤? 什么是倒排索引?为什么它对…...
使用keras-tuner微调神经网络超参数
目录 随机搜索RandomSearch HyperBand 贝叶斯优化BayesianOptimization 附录 本文将介绍keras-tuner提供了三种神经网络超参数调优方法。它们分别是随机搜索RandomSearch、HyperBand和贝叶斯优化BayesianOptimization。 首先需要安装keras-tuner依赖库,安装命令如…...
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
第三部分:高级主题 第十章 高级函数与范式 在现代 JavaScript 开发中,高级函数与函数式编程范式正在逐渐成为开发者追求的目标。这种范式关注于函数的使用,消除副作用,提高代码的可读性和可维护性。 10.1. 高阶函数 高阶函数是…...
LabVIEW光偏振态检测系统
开发一套LabVIEW的高精度光偏振态检测系统,采用机械转动法结合光电探测器和高性能数据采集硬件,能快速、准确地测量光的偏振状态。该系统广泛应用于物理研究、激光技术和光学工业中。 系统组成 该光偏振态检测系统主要由以下硬件和软件模块构成…...
Linux线程(八)线程与信号之间的关系详解
本小节将对线程各方面的细节做深入讨论,其主要包括线程与信号之间牵扯的问题、线程与进程控制(fork()、exec()、exit()等)之间的交互。之所以出现了这些问题,其原因在于线程技术的问世晚于信号、进程控制等,然而线程的…...
红帽操作系统Linux基本命令2( Linux 网络操作系统 06)
本文接着上篇Linux常用命令-1继续往后学习其他常用命令。 2.3 目录操作类命令 1.mkdir命令 mkdir命令用于创建一个目录。该命令的语法为: 上述目录名可以为相对路径,也可以为绝对路径。 mkdir命令的常用参数选项如下。 -p:在创…...
降重秘籍:如何利用ChatGPT将重复率从45%降至10%以下?
AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 重复率高达45%?很多人一查论文的重复率,瞬间想“完了,这次真的要重写了”。但其实不用这么绝望!有了ChatGPT,降重真的没那么难。今天就教你几招&a…...
sql-labs靶场第九关测试报告
目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①寻找注入方法 ②爆库,查看数据库名称 ③爆表,查看security库的所有表 ④爆列,查看users表的所有列 ⑤成功获取用户名…...
AI大模型的转折点,关注哪些机遇?
近期,人工智能领域取得又一突破性进展,OpenAI官方隆重推出了其最新力作——模型o1。这款模型的最大亮点在于,它融合了强化学习(RL)的训练方法,并在模型推理过程中采用了更为深入的内部思维链(ch…...
Stable Diffusion 常用大模型及其特点
SD(Stable Diffusion)的常用大模型及其特点可以归纳如下: 一、基础大模型 SD 1.x 特点:Stable Diffusion的早期版本,主要用于图像生成任务。这里的1.x表示1系列的主要版本,x是一个变量,表示具体…...
macos安装mongodb
文章目录 说明安装和配置安装mongodb配置PATH变量 验证日志及数据存放目录 mac启动和关闭mongodb后台启动失败问题mongodb-compass(GUI) 说明 Homebrew core 列表目前已经将 MongoDB 移除,不再为其提供支持。但是使用国内镜像的brew还是可以安装的!这里直接从官网下…...
IDEA基础开发配置以及和git的联动
1.1方向一:工具介绍 我今天要介绍的就是学习Java大部分情况下都会选择的一款工具-----IDEA,这个和我们熟悉的这个pycharm一样,都是属于这个Jetbrains公司的,虽然我对于这个并不是很了解,但是确实知道一点,…...
【前端】前端数据转化为后端数据
【前端】前端数据转化为后端数据 写在最前面格式化数组代码解释hasOwnProperty是什么? 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~ 🚀 欢迎一起踏上探险之旅,挖掘无限…...
LabVIEW回转支承间隙自动化检测系统
开发了一种基于LabVIEW软件的回转支承间隙检测系统,通过高精度传感器和数据采集卡,自动化、高效地测量回转支承的轴向间隙和径向间隙,提高了检测精度和生产质量。以下是对系统的详细描述与应用案例分析,希望能为有类似需求的开发者…...
数据结构-4.3.串的存储结构
一.串的顺序存储: 1.静态数组会由系统自动回收;动态数组需要手动回收; 2.优点:随机存取,可以立即找到所需的字符;缺点:插入和删除较麻烦; 3.串的顺序存储方案: 对于方…...
LeetCode讲解篇之34. 在排序数组中查找元素的第一个和最后一个位置
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 这题让我们求目标值的左边界和右边界,我们可以采用二分查找搜索有序数组内大于等于目标值的最左边的下标 然后我们只需要在有序数组查找一下大于等于target的最左边下标 如果该下标越界或者下标对应…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
