当前位置: 首页 > news >正文

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]``
类似这个,这个是用于基础的认证,比方说用户需要登陆才能确认的,使用这个比较方便。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/07b878dcf2d641b79e9700d6a8ade683.png)2.特定用户
这类的需求,可以通过获取self.request.user来判断,其中可以通过获取用户是否为超级用户,以及username等判断,大大提高drf的灵活性!![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8ddab551e10942f7a1b7ebc0d0dd9686.png)最后,大家还遇到哪些坑,也可以分享在评论区中,大家一起排雷,祝大家春节喜乐!觉得有用的话可以分享以及关注哈!

相关文章:

DRF开发避坑指南01

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

批量提取多个 Excel 文件内指定单元格的数据

这篇文章将介绍如何从多个相同格式的Excel文件中,批量提取指定单元格的数据,合并后保存到新的工作薄。 全程0代码,可视化操作。 提取前: 提取后: 准备数据 这里准备了3个测试数据 开始提取 打开的卢易表&#xff0…...

#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 &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a…...

头歌实训作业 算法设计与分析-贪心算法(第5关:求解流水作业调度问题)

问题描述 有 n 个作业&#xff08;编号为1&#xff5e;n&#xff09;要在由两台机器 M 1和 M 2 组成的流水线上完成加工。每个作业加工的顺序都是先在 M 1​上加工&#xff0c;然后在 M 2 上加工。 M 1 和 M 2 加工作业 i 所需的时间分别为 a i 和 b i&#xff08;1≤i≤n&am…...

Hadoop•搭建完全分布式集群

听说这里是目录哦 一、安装Hadoop&#x1f955;二、配置Hadoop系统环境变量&#x1f96e;三、验证Hadoop系统环境变量是否配置成功&#x1f9c1;四、修改Hadoop配置文件&#x1f36d;五、分发Hadoop安装目录&#x1f9cb;六、分发系统环境变量文件&#x1f368;七、格式化HDFS文…...

SQL-leetcode—1141. 查询近30天活跃用户数

1141. 查询近30天活跃用户数 表&#xff1a;Activity ---------------------- | Column Name | Type | ---------------------- | user_id | int | | session_id | int | | activity_date | date | | activity_type | enum | ---------------------- 该表没有包含重复数据。 …...

总结与展望,龙蜥社区第 30 次运营委员会会议线上召开

2025 年 1 月 20 日&#xff0c;龙蜥社区召开了第 30 次运营委员会线上会议&#xff0c;来自 24 家理事单位的 22 位委员及委员代表出席&#xff0c;本次会议由运营委员凝思软件李晨斌主持。会上总结和回顾了龙蜥社区 1 月运营发展情况&#xff0c;同步了龙蜥社区 3 大运营目标…...

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径&#xff0c;在idea的plugins下面的lib文件夹内&#xff1a;java-decompiler.jar。下面是我自己本地的插件路径&#xff0c;以作参考&#xff1a; D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…...

c++----------------------多态

1.多态 1.1多态的概念 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态)&#xff0c;这⾥我们重点讲运⾏时多态&#xff0c;编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)…...

C语言 指针_野指针 指针运算

野指针&#xff1a; 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09; 指针非法访问&#xff1a; int main() {int* p;//p没有初始化&#xff0c;就意味着没有明确的指向//一个局部变量不初始化&#xff0c;放…...

【JavaEE进阶】Spring留言板实现

目录 &#x1f38d;预期结果 &#x1f340;前端代码 &#x1f384;约定前后端交互接口 &#x1f6a9;需求分析 &#x1f6a9;接口定义 &#x1f333;实现服务器端代码 &#x1f6a9;lombok介绍 &#x1f6a9;代码实现 &#x1f334;运行测试 &#x1f384;前端代码实…...

第25篇 基于ARM A9处理器用C语言实现中断<一>

Q&#xff1a;怎样理解基于ARM A9处理器用C语言实现中断的过程呢&#xff1f; A&#xff1a;同样以一段使用C语言实现中断的主程序为例介绍&#xff0c;和汇编语言实现中断一样这段代码也使用了定时器中断和按键中断。执行该主程序会在DE1-SoC的红色LED上显示流水灯&#xf…...

面向通感一体化的非均匀感知信号设计

文章目录 1 非均匀信号设计的背景分析1.1 基于OFDM波形的感知信号1.2 非均匀信号设计的必要性和可行性1.2 非均匀信号设计的必要性和可行性 3 通感一体化系统中的非均匀信号设计方法3.1 非均匀信号的设计流程&#xff08;1&#xff09;均匀感知信号设计&#xff08;2&#xff0…...

修改docker共享内存shm-size

法1&#xff1a;在创建容器时增加共享内存大小 nvidia-docker run -it -p 10000:22 --name"zm" -v /home/zm:/data ufoym/deepo:all-cu101 /bin/bash --shm-size20G法2&#xff1a;修改正在运行的容器的共享内存设置 查看容器、共享内存 docker ps -a df -lh | gr…...

WIN11 UEFI漏洞被发现, 可以绕过安全启动机制

近日&#xff0c;一个新的UEFI漏洞被发现&#xff0c;可通过多个系统恢复工具传播&#xff0c;微软已经正式将该漏洞标记为追踪编号“CVE-2024-7344”。根据报告的说明&#xff0c;该漏洞能让攻击者绕过安全启动机制&#xff0c;并部署对操作系统隐形的引导工具包。 据TomsH…...

网安加·百家讲坛 | 樊山:数据安全之威胁建模

作者简介&#xff1a;樊山&#xff0c;锦联世纪教育能源工业互联网数字安全CSM(新能源运维师)课程特聘培训讲师&#xff0c;哈尔滨工业大学&#xff08;深圳&#xff09;信飞合创数据合规联合实验室特聘专家&#xff0c;武汉赛博网络安全人才研究中心资深专家&#xff1b;近24年…...

jQuery阶段总结(二维表+思维导图)

引言 经过23天的学习&#xff0c;期间有期末考试&#xff0c;有放假等插曲。本来应该在学校里学习&#xff0c;但是特殊原因&#xff0c;让回家了。但是在家学习的过程&#xff0c;虽然在学&#xff0c;很让我感觉到不一样。但是效果始终还是差点的&#xff0c;本来17、18号左右…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...