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号左右…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
