当前位置: 首页 > 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号左右…...

【LLM】RedisSearch 向量相似性搜索在 SpringBoot 中的实现

整理不易&#xff0c;请不要吝啬你的赞和收藏。 1. 前言 写这篇文章挺不容易的&#xff0c;网络上对于 SpringBoot 实现 Redis 向量相似性搜索的文章总体来说篇幅较少&#xff0c;并且这些文章很多都写得很粗糙&#xff0c;或者不是我想要的实现方式&#xff0c;所以我不得不阅…...

如何为64位LabVIEW配置正确的驱动程序

在安装 64位 LabVIEW 后&#xff0c;确保驱动程序正确配置是关键。如果您首先安装了 32位 LabVIEW 和相关驱动&#xff0c;然后安装了 64位 LabVIEW&#xff0c;需要确保为 64位 LabVIEW 安装和配置适当的驱动程序&#xff0c;才能正常访问硬件设备。以下是详细步骤&#xff1a…...

Redis(5,jedis和spring)

在前面的学习中&#xff0c;只是学习了各种redis的操作&#xff0c;都是在redis命令行客户端操作的&#xff0c;手动执行的&#xff0c;更多的时候就是使用redis的api&#xff08;&#xff09;&#xff0c;进一步操作redis程序。 在java中实现的redis客户端有很多&#xff0c;…...

Git 小白入门教程

&#x1f3af; 这篇文章详细介绍了版本控制的重要性&#xff0c;特别是通过Git实现的分布式版本控制相对于SVN集中式控制的优势。文章首先解释了版本控制的基本概念&#xff0c;强调了在文档或项目多版本迭代中备份与恢复任意版本的能力。接着&#xff0c;重点阐述了Git的历史背…...

Python从0到100(八十五):神经网络与迁移学习在猫狗分类中的应用

在人工智能的浩瀚宇宙中&#xff0c;深度学习犹如一颗璀璨的星辰&#xff0c;引领着机器学习和计算机视觉领域的前沿探索。而神经网络&#xff0c;作为深度学习的核心架构&#xff0c;更是以其强大的数据建模能力&#xff0c;成为解决复杂问题的重要工具。今天&#xff0c;我们…...

代码随想录刷题day14(2)|(链表篇)02.07. 链表相交(疑点)

目录 一、链表理论基础 二、链表相交求解思路 三、相关算法题目 四、疑点 一、链表理论基础 代码随想录 二、链表相交求解思路 链表相交时&#xff0c;是结点的位置&#xff0c;也就是指针相同&#xff0c;不是结点的数值相同&#xff1b; 思路&#xff1a;定义两个指针…...

C++ 复习总结记录九

C 复习总结记录九 主要内容 1、list 介绍及使用 2、list 剖析及模拟实现 3、list 与 vector 对比 一 list 介绍及使用 List 相关文档 1、List 在任意位置进行插入和删除的序列式容器 O(1) &#xff0c;且该容器可前后双向迭代 2、List 底层是带头双向循环链表&#xff…...

数据库性能优化(sql优化)_SQL执行计划02_yxy

数据库性能优化_SQL执行计划详解02 常用操作符解读1.1 表扫描类型操作符1.1.1 CSCN 聚集索引扫描1.1.2 CSEK 聚集索引数据定位1.1.3 SSEK 二级索引数据定位1.1.4 SSCN 直接使用二级索引进行扫描1.2 其他常见操作符1.2.1 BLKUP 二次扫描1.2.2 SLCT 选择1.2.3 PRJT 投影1.2.4 NSE…...

Vivado生成X1或X4位宽mcs文件并固化到flash

1.生成mcs文件 01.在vivado里的菜单栏选择"tools"工具栏 02.在"tools"里选择"生成内存配置文件" 03.配置参数 按照FPGA板上的flash型号进行选型&#xff0c;相关配置步骤可参考下图。 注意&#xff1a;Flash数据传输位宽如果需要选择X4位宽&am…...

在K8S中使用Values文件定制不同环境下的应用配置详解

在Kubernetes&#xff08;简称K8s&#xff09;环境中&#xff0c;应用程序的配置管理是一项关键任务。为了确保应用程序在不同环境&#xff08;如开发、测试、预发布和生产&#xff09;中都能稳定运行&#xff0c;我们需要为每个环境定制相应的配置。Values文件是在使用Helm管理…...