DRF开发避坑指南01
在当今快速发展的Web开发领域,Django REST Framework(DRF)以其强大的功能和灵活性成为了众多开发者的首选。然而,错误的使用方法不仅会导致项目进度延误,还可能影响性能和安全性。本文将从我个人本身遇到的相关坑来给大家避坑。

一、API性能优化
坑:响应太慢!!!!!!
import os
from django_filters.rest_framework import DjangoFilterBackendfrom rest_framework import viewsets
from rest_framework import filters
from rest_framework import permissions, authentication
from rest_framework.decorators import action
from rest_framework_simplejwt.authentication import JWTAuthenticationfrom utils.rest_framework_util.pagination import CommonPagination
from utils.rest_framework_util.response import rtn_success_info, rtn_error_info
from utils.rest_framework_util.excel_util import ExcelUtil, write_excel_file
from utils.utils import get_current_time_format
from utils.oss.tx_upload import CommonUpload
from drf_yasg import openapi__all__ = {"CommonViewSet","CommonUserViewSet"
}from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapiclass CommonViewSet(viewsets.ModelViewSet):permission_classes = ()authentication_classes = ()filter_backends = [ DjangoFilterBackend, filters.SearchFilter]search_fields = ["id"]save_export_folder = "static/save_export/"pagination_class = CommonPaginationdef list(self, request, *args, **kwargs):queryset = self.filter_queryset(self.get_queryset())len_model = len(queryset)page = self.paginate_queryset(queryset)if page is not None:serializer = self.get_serializer(page, many=True)response_data = {"total": len_model,"list": serializer.data}return rtn_success_info(response_data, msg="查询数据成功")serializer = self.get_serializer(queryset, many=True)return rtn_success_info(serializer.data)def retrieve(self, request, *args, **kwargs):instance = self.get_object()serializer = self.get_serializer(instance)return rtn_success_info(serializer.data)def update(self, request, *args, **kwargs):"""put 修改"""try:partial = kwargs.pop('partial', False)instance = self.get_object()serializer = self.get_serializer(instance, data=request.data, partial=partial)serializer.is_valid(raise_exception=True)self.perform_update(serializer)if getattr(instance, '_prefetched_objects_cache', None):# If 'prefetch_related' has been applied to a queryset, we need to# forcibly invalidate the prefetch cache on the instance.instance._prefetched_objects_cache = {}return rtn_success_info(serializer.data, msg='修改数据成功')except Exception as e:return rtn_error_info(msg=e)def destroy(self, request, *args, **kwargs):instance = self.get_object()self.perform_destroy(instance)return rtn_success_info(msg="数据删除成功")def perform_destroy(self, instance):instance.delete()def create(self, request, *args, **kwargs):serializer = self.get_serializer(data=request.data)serializer.is_valid(raise_exception=True)self.perform_create(serializer)return rtn_success_info(serializer.data, msg="创建数据成功")@action(detail=False, methods=['POST'])def data_import(self, request, *args, **kwargs):response_data_list = []file = request.FILES.get("file", None)if file is None:return rtn_error_info("需要传入file文件")else:title_list, data_list = ExcelUtil(file).read_data()serializer_class = self.get_serializer_class()model = serializer_class.Meta.modeltry:if model is not None:model.objects.create()for create_data in data_list:response_data = {}for index_, title in enumerate(title_list):response_data[title] = create_data[index_]if response_data.get('id', None) is not None:response_data.pop("id")serializer = self.get_serializer(data=response_data)if serializer.is_valid():# 创建self.perform_create(serializer)except Exception as e:return rtn_error_info(f"数据导入失败:{e}")response_data_list = data_listreturn rtn_success_info(data=response_data_list, msg='导入数据成功')@action(detail=False, methods=['POST'])def data_export(self, request, *args, **kwargs):id_list = request.data.get('ids', None)queryset = self.get_queryset()row_data_list = []is_first = Falsetitle_list = []title = ""for data in queryset:title = data.__class__.__name__if not is_first:data_list = []for data_meta in data._meta.fields:data_list.append(data_meta.name)title_list.append(data_meta.name)row_data_list.append(data_list) # titleis_first = Truebreakfor value_data in queryset.values():data_info = []if id_list is not None:for id_ in id_list:if int(value_data['id']) == int(id_):for title in title_list:data_info.append(value_data[title])else:for title in title_list:data_info.append(value_data[title])if len(data_info) > 0:row_data_list.append(data_info)excel_file_name = f"{title}_{get_current_time_format('%Y_%m_%d_%H_%M_%S')}.xlsx"if not os.path.exists(self.save_export_folder):os.makedirs(self.save_export_folder)write_excel_file(row_data_list, f"{self.save_export_folder}{excel_file_name}")if os.path.exists(f"{self.save_export_folder}{excel_file_name}"):url = CommonUpload().cos_upload_file(f"{self.save_export_folder}{excel_file_name}")data = {'excel_url': url}return rtn_success_info(data, '导出成功')return rtn_error_info("导出失败")class CommonUserViewSet(CommonViewSet):"""带用户权限的ViewSetArgs:viewsets (_type_): _description_Returns:_type_: _description_"""permission_classes = [permissions.IsAuthenticated]authentication_classes = [JWTAuthentication, authentication.SessionAuthentication,authentication.BasicAuthentication]def create(self, request, *args, **kwargs):data = request.datadata["user"] = request.user.idserializer = self.get_serializer(data=data)serializer.is_valid(raise_exception=True)self.perform_create(serializer)return rtn_success_info(serializer.data, msg="创建数据成功")def list(self, request, *args, **kwargs):queryset = self.filter_queryset(self.get_queryset())len_model = len(queryset)page = self.paginate_queryset(queryset)if page is not None:serializer = self.get_serializer(page, many=True)response_data = {"total": len_model,"list": serializer.data}return rtn_success_info(response_data, msg="查询数据成功")serializer = self.get_serializer(queryset, many=True)return rtn_success_info(serializer.data)
以这块代码为例,大家会发现一个问题,虽然都封装了ViewSet,但是他的响应速度比之前慢很多,原因何在,问题就出现在len_model = len(queryset)上,因为当前的len(queryset)会遍历每一个model,导致性能缓慢,正确的修改方式是使用queryset.count(),会大幅度的提高性能,直接获取里面的变量。
图片
二、复杂权限管理
针对于这类的权限管理,其实DRF也给咱们弄好了,但是基于实际业务场景的复杂性,本人也提供给大家一个参考的可定制化的代码!
1.通过定制通用类的permissions
class CommonUserViewSet(CommonViewSet):"""带用户权限的ViewSetArgs:viewsets (_type_): _description_Returns:_type_: _description_"""permission_classes = [permissions.IsAuthenticated]authentication_classes = [JWTAuthentication, authentication.SessionAuthentication,authentication.BasicAuthentication]``
类似这个,这个是用于基础的认证,比方说用户需要登陆才能确认的,使用这个比较方便。
2.特定用户
这类的需求,可以通过获取self.request.user来判断,其中可以通过获取用户是否为超级用户,以及username等判断,大大提高drf的灵活性!最后,大家还遇到哪些坑,也可以分享在评论区中,大家一起排雷,祝大家春节喜乐!觉得有用的话可以分享以及关注哈!
相关文章:
DRF开发避坑指南01
在当今快速发展的Web开发领域,Django REST Framework(DRF)以其强大的功能和灵活性成为了众多开发者的首选。然而,错误的使用方法不仅会导致项目进度延误,还可能影响性能和安全性。本文将从我个人本身遇到的相关坑来给大…...
批量提取多个 Excel 文件内指定单元格的数据
这篇文章将介绍如何从多个相同格式的Excel文件中,批量提取指定单元格的数据,合并后保存到新的工作薄。 全程0代码,可视化操作。 提取前: 提取后: 准备数据 这里准备了3个测试数据 开始提取 打开的卢易表࿰…...
#HarmonyOS篇:build-profile.json5里面配置productsoh-package.json5里面dependencies依赖引入
oh-package.json5 用于描述包名、版本、入口文件和依赖项等信息。 {"license": "","devDependencies": {},"author": "","name": "entry","description": "Please describe the basic…...
Spring集成Redis|通用Redis工具类
一、基础使用 概述 在SpringBoot中一般使用RedisTemplate提供的方法来操作Redis。那么使用SpringBoot整合Redis需要 那些步骤呢。 1、 JedisPoolConfig (这个是配置连接池) 2、 RedisConnectionFactory 这个是配置连接信息,这里的RedisConnectionFactory是一个接 …...
Vue中设置报错页面和“Uncaught runtime errors”弹窗关闭
文章目录 前言操作步骤大纲1.使用Vue自带的报错捕获机制添加报错信息2.在接口报错部分添加相同机制3.把报错信息添加到Vuex中方便全局使用4.添加报错页面备用5.app页面添加if判断替换报错界面 效果备注:vue项目中Uncaught runtime errors:怎样关闭 前言 在开发Vue项…...
【力扣】219. 存在重复元素 II
题目 给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在,返回 true ;否则,返回 false 。 示例 1: 输入:…...
头歌实训作业 算法设计与分析-贪心算法(第5关:求解流水作业调度问题)
问题描述 有 n 个作业(编号为1~n)要在由两台机器 M 1和 M 2 组成的流水线上完成加工。每个作业加工的顺序都是先在 M 1上加工,然后在 M 2 上加工。 M 1 和 M 2 加工作业 i 所需的时间分别为 a i 和 b i(1≤i≤n&am…...
Hadoop•搭建完全分布式集群
听说这里是目录哦 一、安装Hadoop🥕二、配置Hadoop系统环境变量🥮三、验证Hadoop系统环境变量是否配置成功🧁四、修改Hadoop配置文件🍭五、分发Hadoop安装目录🧋六、分发系统环境变量文件🍨七、格式化HDFS文…...
SQL-leetcode—1141. 查询近30天活跃用户数
1141. 查询近30天活跃用户数 表:Activity ---------------------- | Column Name | Type | ---------------------- | user_id | int | | session_id | int | | activity_date | date | | activity_type | enum | ---------------------- 该表没有包含重复数据。 …...
总结与展望,龙蜥社区第 30 次运营委员会会议线上召开
2025 年 1 月 20 日,龙蜥社区召开了第 30 次运营委员会线上会议,来自 24 家理事单位的 22 位委员及委员代表出席,本次会议由运营委员凝思软件李晨斌主持。会上总结和回顾了龙蜥社区 1 月运营发展情况,同步了龙蜥社区 3 大运营目标…...
idea对jar包内容进行反编译
1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径,在idea的plugins下面的lib文件夹内:java-decompiler.jar。下面是我自己本地的插件路径,以作参考: D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…...
c++----------------------多态
1.多态 1.1多态的概念 多态(polymorphism)的概念:通俗来说,就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态),这⾥我们重点讲运⾏时多态,编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)…...
C语言 指针_野指针 指针运算
野指针: 概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) 指针非法访问: int main() {int* p;//p没有初始化,就意味着没有明确的指向//一个局部变量不初始化,放…...
【JavaEE进阶】Spring留言板实现
目录 🎍预期结果 🍀前端代码 🎄约定前后端交互接口 🚩需求分析 🚩接口定义 🌳实现服务器端代码 🚩lombok介绍 🚩代码实现 🌴运行测试 🎄前端代码实…...
第25篇 基于ARM A9处理器用C语言实现中断<一>
Q:怎样理解基于ARM A9处理器用C语言实现中断的过程呢? A:同样以一段使用C语言实现中断的主程序为例介绍,和汇编语言实现中断一样这段代码也使用了定时器中断和按键中断。执行该主程序会在DE1-SoC的红色LED上显示流水灯…...
面向通感一体化的非均匀感知信号设计
文章目录 1 非均匀信号设计的背景分析1.1 基于OFDM波形的感知信号1.2 非均匀信号设计的必要性和可行性1.2 非均匀信号设计的必要性和可行性 3 通感一体化系统中的非均匀信号设计方法3.1 非均匀信号的设计流程(1)均匀感知信号设计(2࿰…...
修改docker共享内存shm-size
法1:在创建容器时增加共享内存大小 nvidia-docker run -it -p 10000:22 --name"zm" -v /home/zm:/data ufoym/deepo:all-cu101 /bin/bash --shm-size20G法2:修改正在运行的容器的共享内存设置 查看容器、共享内存 docker ps -a df -lh | gr…...
WIN11 UEFI漏洞被发现, 可以绕过安全启动机制
近日,一个新的UEFI漏洞被发现,可通过多个系统恢复工具传播,微软已经正式将该漏洞标记为追踪编号“CVE-2024-7344”。根据报告的说明,该漏洞能让攻击者绕过安全启动机制,并部署对操作系统隐形的引导工具包。 据TomsH…...
网安加·百家讲坛 | 樊山:数据安全之威胁建模
作者简介:樊山,锦联世纪教育能源工业互联网数字安全CSM(新能源运维师)课程特聘培训讲师,哈尔滨工业大学(深圳)信飞合创数据合规联合实验室特聘专家,武汉赛博网络安全人才研究中心资深专家;近24年…...
jQuery阶段总结(二维表+思维导图)
引言 经过23天的学习,期间有期末考试,有放假等插曲。本来应该在学校里学习,但是特殊原因,让回家了。但是在家学习的过程,虽然在学,很让我感觉到不一样。但是效果始终还是差点的,本来17、18号左右…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
