软删除(Soft Delete)是一种数据删除策略,它并不真正从数据库中删除记录,而是通过标记(如 is_deleted 字段)来表示记录已被删除。

这样做的好处是可以保留数据历史,支持数据恢复和审计。

在 Django 里可以通过 自定义 Manager + 重写 delete 方法 来实现。


1. 在模型里增加 is_delete 字段

from django.db import modelsclass BaseModel(models.Model):is_delete = models.BooleanField(default=False, verbose_name="是否删除")class Meta:abstract = True  # 抽象基类,不会建表

这样所有继承 BaseModel 的表都有 is_delete 字段。


2. 自定义 Manager(默认过滤掉删除的记录)

class ActiveManager(models.Manager):def get_queryset(self):# 默认只返回 is_delete=False 的数据return super().get_queryset().filter(is_delete=False)

3. 在模型里应用 Manager

class User(BaseModel):name = models.CharField(max_length=100)# managersobjects = ActiveManager()   # 默认只取未删除的all_objects = models.Manager()  # 需要时可以取所有(包括已删除的)

这样:

User.objects.all()        # 只会查 is_delete=False
User.all_objects.all()    # 不加过滤,所有数据都能查

4. 重写 delete() 方法(软删除)

class User(BaseModel):name = models.CharField(max_length=100)objects = ActiveManager()all_objects = models.Manager()def delete(self, using=None, keep_parents=False):self.is_delete = Trueself.save(update_fields=['is_delete'])  # 只更新 is_delete 字段

这样:

u = User.objects.get(id=1)
u.delete()  # 不会真正删除,只会把 is_delete 置为 True

5. 如果要做批量删除

Django 的 QuerySet.delete() 默认会直接删掉数据,所以我们也可以自定义一个 QuerySet 来支持批量软删除:

class SoftDeleteQuerySet(models.QuerySet):def delete(self):return super().update(is_delete=True)

结合 Manager 使用:

class ActiveManager(models.Manager):def get_queryset(self):return SoftDeleteQuerySet(self.model, using=self._db).filter(is_delete=False)

这样就支持:

User.objects.filter(name="Tom").delete()  # 也会变成软删除

总结

  1. is_delete 字段标记是否删除。
  2. 自定义 Manager 过滤掉已删除的数据。
  3. 重写 delete() 实现软删除逻辑。
  4. 如有需要,配合自定义 QuerySet 处理批量软删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96130.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96130.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96130.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaEE 进阶第四期:开启前端入门之旅(四)

专栏:JavaEE 进阶跃迁营 个人主页:手握风云 目录 一、常用CSS 1.1. border 1.2. width/height 1.3. padding:内边距 1.4. margin:外边距 二、初始JavaScript 2.1. JavaScript是什么 2.2. 发展历史 2.3. JavaScript 和 HT…

学习日记-SpringMVC-day49-9.4

知识点:1.RequestMapping(3)知识点核心内容重点RequestMapping注解的parameters属性通过parameters指定请求参数条件(如bookID),控制请求匹配规则(必须包含/排除特定参数或值)参数存…

【Day 50 】Linux-nginx反向代理与负载均衡

概述在现代 Web 架构中,Nginx 作为高并发、高性能的 HTTP 和反向代理服务器,被广泛应用于提升服务性能、增强系统安全性和实现负载均衡。其中,反向代理能够隐藏后端服务器信息并优化请求处理流程,负载均衡则可将请求分发到多个后端…

vue中配置 ts

在 Vue 项目中配置 TypeScript(TS)可以提升代码的类型安全性和开发体验。以下是在 Vue 项目(基于 Vite)中配置 TypeScript 的详细步骤和关键配置: 一、创建支持 TypeScript 的 Vue 项目 如果是新建项目,推…

阿里云镜像地址获取,并安装 docker的mysql和nginx等服务,java,python,ffmpeg,go等环境

阿里云那个镜像地址获取 阿里云镜像加速器不是一个通用的 registry.cn-hangzhou.aliyuncs.com,而是你账号专属的,比如这样: https://abcd1234.mirror.aliyuncs.com👉 登录阿里云控制台获取: 阿里云镜像加速器 然后替…

conda环境导出

1. 激活你想要打包的环境首先,确保你激活了你要打包的 conda 环境:conda activate qwen2. 导出环境配置使用 conda 命令将当前环境的配置导出为一个 .yml 文件,记录下环境中所有的依赖和版本:conda list --export > techgpt_en…

openEuler2403安装部署Kafka

文章目录 openEuler2403安装部署Kafka with KRaft一、前言1.简介2.架构3.环境 二、正文1.部署服务器2.基础环境1)JDK 安装部署2)关闭防火墙 3.单机部署1)下载软件包2)修改配置文件3)格式化存储目录4)单机启…

发布工业智能体,云从科技打造制造业AI“运营大脑”

近日,在2025世界智能产业博览会重庆市工业智能体首发仪式现场,云从科技重磅发布经营决策-产线运营智能体,为制造业的智能化转型提供了全新的解决方案。该智能体的亮相,不仅代表着人工智能技术在工业领域的深度应用,更标…

【Linux基础】parted命令详解:从入门到精通的磁盘分区管理完全指南

目录 前言 1 parted命令概述 1.1 什么是parted 1.2 parted与fdisk的对比 1.3 parted的主要优势 2 parted命令的安装与基本语法 2.1 在不同Linux发行版中安装parted 2.2 parted的基本语法 2.3 parted的工作模式 3 parted交互式命令详解 3.1 交互式操作流程 3.2 主要…

如何在路由器上配置DHCP服务器?

在路由器上配置DHCP服务器的步骤因品牌(如TP-Link、华为、小米、华硕等)略有差异,但核心流程一致,主要包括登录管理界面、开启DHCP功能、设置IP地址池及相关参数。以下是通用操作指南: 一、准备工作 确保电脑/手机已连…

HTML和CSS学习

HTML学习 注释 <!-- -->组成 告诉浏览器我是html文件<!DOCTYPE html> <title>浏览器标签</title> <body> <!--- 其中是主要内容 ---> <p> 段落 </p> </body> </html> (结束点…

OpenTenBase vs MySQL vs Oracle,企业级应用数据库实盘对比分析

摘要 因为工作久了的缘故&#xff0c;接触过不少数据库。公司的管理系统用的MySQL&#xff0c;财务系统用的Oracle。随着时代发展&#xff0c;国产开源数据库已经在性能上能与这些国际知名顶尖数据库品牌相媲美&#xff0c;其中OpenTenBase以其开放环境和优越性能脱颖而出&…

Oracle 备份与恢复常见的七大问题

为了最大限度保障数据的安全性&#xff0c;同时能在不可预计灾难的情况下保证数据的快速恢复&#xff0c;需要根据数据的类型和重要程度制定相应的备份和恢复方案。在这个过程中&#xff0c;DBA的职责就是要保证数据库&#xff08;其它数据由其它岗位负责&#xff09;的高可用和…

StringBuilder类的数据结构和扩容方式解读

目录 StringBuilder是什么 核心特性&#xff1a; StringBuilder数据结构 1. 核心存储结构&#xff08;基于父类 AbstractStringBuilder&#xff09; 2. 类定义与继承关系 3. 数据结构的核心特点 StringBuilder数据结构的初始化方式 1. 无参构造&#xff1a;默认初始容量…

LangChain实战(十七):构建与PDF/PPT文档对话的AI助手

本文是《LangChain实战课》系列的第十七篇,将专篇深入讲解如何构建能够与PDF和PPT文档进行智能对话的AI助手。通过学习本文,您将掌握复杂格式文档的解析技巧、文本与表格处理技术,以及实现精准问答的系统方法。 前言 在日常工作和学习中,PDF和PPT文档是我们最常接触的文档…

鱼眼相机模型

鱼眼相机模型 最近涉及鱼眼相机模型、标定使用等&#xff0c;作为记录&#xff0c;更新很久不曾更新的博客。 文章目录鱼眼相机模型1 相机成像2 鱼眼模型3 畸变3.1 适用针孔和MEI3.2 Kannala-Brandt鱼眼模型4 代码实现1 相机成像 针孔相机&#xff1a;所有光线从一个孔&#xf…

大语言模型提示词工程详尽实战指南

引言&#xff1a;与大型语言模型&#xff08;LLM&#xff09;高效对话的艺术大型语言模型&#xff08;LLM&#xff09;——例如我们熟知的GPT系列、Claude、Llama等——在自然语言处理&#xff08;NLP&#xff09;领域展现了惊人的能力&#xff0c;能够执行文本摘要、翻译、代码…

HTTP 请求体格式详解

1. 概览与概念 Content-Type&#xff1a;HTTP 请求/响应头&#xff0c;表示消息体的媒体类型&#xff08;MIME type&#xff09;。服务端用它决定如何解析请求体。常见场景&#xff1a; 纯结构化数据&#xff08;JSON&#xff09; → application/json表单 文件上传 → multip…

事务设置和消息分发

事务 RabbitMQ是基于AMQP协议实现的&#xff0c;该协议实现了事务机制&#xff0c;因此RabbitMQ也支持事务机制. SpringAMQP也提供了对事务相关的操作&#xff0c;RabbitMQ事务允许开发者确保消息的发送和接收是原子性的&#xff0c;要么 全部成功&#xff0c;要么全部失败.| 前…

Python 中 try / except / else / finally 异常处理详解

1. 基本结构 try:# 可能会抛出异常的代码 except SomeException as e:# 捕获并处理异常 else:# 如果 try 中代码没有异常&#xff0c;就执行这里 finally:# 无论是否发生异常&#xff0c;最后都会执行这里2. 各部分的作用 try 用途&#xff1a;包含可能发生异常的代码段。如果代…