深入解析 Django 中数据删除的最佳实践:以动态管理镜像版本为例
文章目录
- 引言
- 场景与模型设计
- 场景描述
- 删除操作详解
- 1. 删除单个 Tag
- 2. 批量删除 Tags
- 3. 删除前确认
- 4. 日志记录
- 高阶优化与问题分析
- 1. 外键约束与误删保护
- 2. 并发删除的冲突处理
- 3. 使用软删除
- 结合 Django Admin 的实现
- 总结与实践思考
引言
在现代应用开发中,服务和版本的动态管理是常见需求。例如,开发一个支持多版本的服务管理系统,其中需要定期删除不再使用的镜像版本(Tags)。如何在 Django 项目中安全、高效地删除这些数据?有哪些常见的坑需要注意?
本文将以一个动态管理系统为例,深入讲解 Django 的删除逻辑、设计模式及最佳实践。
场景与模型设计
场景描述
假设我们正在开发一个支持多服务的镜像版本管理平台:
- 每个服务(如 Redis、MySQL)可以有多个镜像版本。
- 需要支持动态增删镜像版本(Tag),例如删除过期版本
redis:6.2.6
。 - 删除逻辑需要兼顾性能和安全,避免误删或关联数据丢失。
模型设计如下:
from django.db import models
from django.utils.timezone import nowclass Service(models.Model):"""服务表"""name = models.CharField("服务名称", max_length=50, unique=True)create_time = models.DateTimeField("创建时间", default=now)class Meta:db_table = "service"ordering = ("-id",)def __str__(self):return self.nameclass ImageTag(models.Model):"""镜像标签表"""image = models.CharField("镜像名称", max_length=128)tag = models.CharField("版本标签", max_length=50)create_time = models.DateTimeField("创建时间", default=now)service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="image_tags")class Meta:db_table = "image_tag"ordering = ("-id",)def __str__(self):return f"{self.image}:{self.tag}"
注意:在设计时,
Service
表通过外键与ImageTag
表建立一对多关联。镜像版本(Tag)依赖具体服务存在。
删除操作详解
1. 删除单个 Tag
需求:删除镜像 redis
的版本 6.2.6
。
代码示例:
# 查询并删除单个 Tag
image_tag = ImageTag.objects.get(image="redis", tag="6.2.6")
image_tag.delete()
输出:
>>> 删除镜像标签: redis:6.2.6
2. 批量删除 Tags
需求:删除镜像 redis
所有 6.x
版本的 Tags。
代码示例:
# 批量删除
ImageTag.objects.filter(image="redis", tag__startswith="6.").delete()
输出:
>>> 删除以下镜像版本:
- redis:6.2.6
- redis:6.0.9
3. 删除前确认
在删除前,通过打印或日志记录,确认将要删除的镜像版本,避免误删。
tags_to_delete = ImageTag.objects.filter(image="redis", tag__startswith="6.")
for tag in tags_to_delete:print(f"即将删除: {tag.image}:{tag.tag}")# 确认后删除
tags_to_delete.delete()
输出:
即将删除: redis:6.2.6
即将删除: redis:6.0.9
4. 日志记录
通过引入日志记录操作,追踪删除记录,便于后续审计:
import logginglogger = logging.getLogger(__name__)image_tag = ImageTag.objects.get(image="redis", tag="6.2.6")
logger.info(f"删除镜像标签: {image_tag.image}:{image_tag.tag}")
image_tag.delete()
高阶优化与问题分析
1. 外键约束与误删保护
当前外键使用 on_delete=models.CASCADE
,即删除服务会级联删除所有 Tags。如果需要保护关联数据,可以改为:
PROTECT
:阻止删除服务,强制保留关联的 Tags。SET_NULL
:删除服务时将 Tags 的service
字段置为NULL
。
service = models.ForeignKey(Service, on_delete=models.PROTECT)
2. 并发删除的冲突处理
多个用户同时删除数据可能引发冲突或覆盖操作。可以通过事务管理保证一致性:
from django.db import transactiontry:with transaction.atomic():image_tag = ImageTag.objects.get(image="redis", tag="6.2.6")image_tag.delete()
except ImageTag.DoesNotExist:print("镜像标签不存在,可能已被其他用户删除。")
3. 使用软删除
如果需要保留删除记录(如审计需求),可以引入软删除逻辑:
class SoftDeleteModel(models.Model):is_deleted = models.BooleanField(default=False)delete_time = models.DateTimeField(null=True, blank=True)def delete(self):self.is_deleted = Trueself.delete_time = now()self.save()class Meta:abstract = True
继承 SoftDeleteModel
,实现软删除:
class ImageTag(SoftDeleteModel):# 其他字段省略pass
结合 Django Admin 的实现
配置 Django Admin,使删除操作更加可控:
@admin.register(ImageTag)
class ImageTagAdmin(admin.ModelAdmin):list_display = ("id", "image", "tag", "service", "create_time")search_fields = ("image", "tag")def delete_model(self, request, obj):print(f"管理员 {request.user} 删除了镜像标签: {obj.image}:{obj.tag}")obj.delete()
总结与实践思考
在 Django 项目中,数据删除需要注意以下几点:
- 精确筛选:确保查询条件准确,避免误删。
- 日志追踪:通过日志记录,确保操作可审计。
- 软删除机制:在某些业务场景下,保留删除记录比直接物理删除更安全。
- 扩展场景:可以结合分页、权限管理等,进一步完善增删改查功能。
相关文章:
深入解析 Django 中数据删除的最佳实践:以动态管理镜像版本为例
文章目录 引言场景与模型设计场景描述 删除操作详解1. 删除单个 Tag2. 批量删除 Tags3. 删除前确认4. 日志记录 高阶优化与问题分析1. 外键约束与误删保护2. 并发删除的冲突处理3. 使用软删除 结合 Django Admin 的实现总结与实践思考 引言 在现代应用开发中,服务和…...
【java】sdkman-java多环境切换工具
#java #env #sdk #lcshand 首先我们来复习一下,可参考我原来的文章: python多个版本的切换可用pyenv nodejs多个版本的切换可用nvm 同样,java多个版本的切换可用sdkman和jenv,我偏重于使用sdkman,因为有时候我也需要…...
11.25c++继承、多态
练习: 编写一个 武器类 class Weapon{int atk; }编写3个武器派生类:短剑,斧头,长剑 class knife{int spd; }class axe{int hp; }class sword{int def; }编写一个英雄类 class Hero{int atk;int def;int spd;int hp; public:所有的…...

STM32F103外部中断配置
一、外部中断 在上一节我们介绍了STM32f103的嵌套向量中断控制器,其中包括中断的使能、失能、中断优先级分组以及中断优先级配置等内容。 1.1 外部中断/事件控制器 在STM32f103支持的60个可屏蔽中断中,有一些比较特殊的中断: 中断编号13 EXTI…...

阿里电商大整合,驶向价值竞争新航道
阿里一出手就是王炸。11月21日,阿里公布了最新动作:将国内和海外电商业务整合,成立新的电商事业群。这是阿里首次将所有电商业务整合到一起,也对电商行业未来发展有着借鉴意义。阿里为何要这么干?未来又将给行业带来哪…...
等保测评在云计算方面的应用讲解
等保测评(信息安全等级保护测评)在云计算方面的应用主要聚焦于如何满足等级保护相关要求,并确保云计算平台及其上运行的业务系统的安全性。以下是主要内容的讲解: 1. 云计算中的等保测评概述 等保测评是在我国网络安全等级保护制…...

QML TableView 实例演示 + 可能遇到的一些问题(Qt_6_5_3)
一、可能遇到的一些问题 Q1:如何禁用拖动? 在TableView下加一句代码即可: interactive: false 补充:这个属性并不专属于TableView,而是一个通用属性。很多Controls下的控件都可以使用,其主要作用就是控…...
SpringBoot(三十九)SpringBoot集成RabbitMQ实现流量削峰添谷
前边我们有具体的学习过RabbitMQ的安装和基本使用的情况。 但是呢,没有演示具体应用到项目中的实例。 这里使用RabbitMQ来实现流量的削峰添谷。 一:添加pom依赖 <!--rabbitmq-需要的 AMQP 依赖--> <dependency><groupId>org.springfr…...
前端 Vue 3 后端 Node.js 和Express 结合cursor常见提示词结构
cursor 提示词 后端提示词 请为我开发一个基于 Node.js 和Express 框架的 Todo List 后端项目。项目需要实现以下四个 RESTful API 接口: 查询所有待办事项 接口名: GET /api/get-todo功能: 从数据库的’list’集合中查询并返回所有待办事项参数: 无返回: 包含所…...

类和对象(下):点亮编程星河的类与对象进阶之光
再探构造函数 在实现构造函数时,对成员变量进行初始化主要有两种方式: 一种是常见的在函数体内赋值进行初始化;另一种则是通过初始化列表来完成初始化。 之前我们在构造函数中经常采用在函数体内对成员变量赋值的方式来给予它们初始值。例如&…...

42.接雨水
目录 题目过程解法 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 过程 发现有特殊情况就是,最高峰的地方,如果右边小于他,然后再右边也都很小的话,…...
使用Java代码操作Kafka(五):Kafka消费 offset API,包含指定 Offset 消费以及指定时间消费
文章目录 1、指定 Offset 消费2、指定时间消费 1、指定 Offset 消费 auto.offset.reset earliest | latest | none 默认是 latest (1)earliest:自动将偏移量重置为最早的偏移量,–from-beginning (2)lates…...

Ubuntu安装不同版本的opencv,并任意切换使用
参考: opencv笔记:ubuntu安装opencv以及多版本共存 | 高深远的博客 https://zhuanlan.zhihu.com/p/604658181 安装不同版本opencv及共存、切换并验证。_pkg-config opencv --modversion-CSDN博客 Ubuntu下多版本OpenCV共存和切换_ubuntu20如同时安装o…...

突破内存限制:Mac Mini M2 服务器化实践指南
本篇文章,我们聊聊如何使用 Mac Mini M2 来实现比上篇文章性价比更高的内存服务器使用,分享背后的一些小的思考。 希望对有类似需求的你有帮助。 写在前面 在上文《ThinkPad Redis:构建亿级数据毫秒级查询的平民方案》中,我们…...

【排版教程】Word、WPS 分节符(奇数页等) 自动变成 分节符(下一页) 解决办法
毕业设计排版时,一般要求每章节的起始页为奇数页,空白页不显示页眉和页脚。具体做法如下: 1 Word 在一个章节的内容完成后,在【布局】中,点击【分隔符】,然后选择【奇数页】 这样在下一章节开始的时&…...

【在Linux世界中追寻伟大的One Piece】多线程(二)
目录 1 -> 分离线程 2 -> Linux线程互斥 2.1 -> 进程线程间的互斥相关背景概念 2.2 -> 互斥量mutex 2.3 -> 互斥量的接口 2.4 -> 互斥量实现原理探究 3 -> 可重入VS线程安全 3.1 -> 概念 3.2 -> 常见的线程不安全的情况 3.3 -> 常见的…...

flink学习(8)——窗口函数
增量聚合函数 ——指窗口每进入一条数据就计算一次 例如:要计算数字之和,进去一个12 计算结果为20, 再进入一个7 ——结果为27 reduce aggregate(aggregateFunction) package com.bigdata.day04;public class _04_agg函数 {public static …...

「实战应用」如何用图表控件LightningChart .NET实现散点图?(一)
LightningChart .NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科…...

鸿蒙Native使用Demo
DevecoStudio使用Native 今天,给大家带来的是关于DevecoStudio中使用Native进行开发 个人拙见:为什么要使用Native?无论是JS还是TS在复杂的情况下运行速度,肯定不如直接操作内存的C/C的运行速度快,所以,会选择使用Native;这里面的过程是什么?通过映射转化,使用napi提供的接口…...

29.UE5蓝图的网络通讯,多人自定义事件,变量同步
3-9 蓝图的网络通讯、多人自定义事件、变量同步_哔哩哔哩_bilibili 目录 1.网络通讯 1.1玩家Pawn之间的同步 1.2事件同步 1.3UI同步 1.4组播 1.5变量同步 1.网络通讯 1.1玩家Pawn之间的同步 创建一个第三人称项目 将网络模式更改为监听服务器,即将房主作为…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
Docker、Wsl 打包迁移环境
电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本: 2.2.4.0 内核版本: 5.15.153.1-2 WSLg 版本: 1.0.61 MSRDC 版本: 1.2.5326 Direct3D 版本: 1.611.1-81528511 DXCore 版本: 10.0.2609…...
【大厂机试题解法笔记】矩阵匹配
题目 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式 N M K N*M矩阵 输…...
【Redis】Redis从入门到实战:全面指南
Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...