如何在Django REST Framework中实现删除操作时自动更新删除日期字段?
如何在Django REST Framework中实现软删除(更新deletion_date而非删除对象)
我是Django REST Framework的新手,我的数据库表包含4个字段(id、chip、creation date、deletion date)。前端设有一个删除芯片的按钮,目前仅完成模型创建与数据库迁移工作,且实现了一条用于列出表中所有数据的GET路由。当前需求为:点击删除按钮时,并非直接删除对象,而是将该对象的deletion_date字段设置为删除操作发生的时间(而非保持为空)。请教如何实现这一结合删除与更新的操作?
我的模型代码如下:
class Gateway(models.Model): id = models.AutoField(primary_key=True) gateway_chip = models.CharField(max_length=20, unique=True) creation_date = models.DateTimeField() deletion_date = models.DateTimeField() class Meta: db_table = 'GATEWAY'
嘿,我来帮你搞定这个软删除需求~其实核心思路就是把原本的删除操作替换成更新deletion_date字段的逻辑,下面一步步来实现:
第一步:先优化你的模型
首先得调整模型字段的配置,让它更符合软删除的场景:
class Gateway(models.Model): id = models.AutoField(primary_key=True) gateway_chip = models.CharField(max_length=20, unique=True) # 自动填充创建时间,不用手动传入 creation_date = models.DateTimeField(auto_now_add=True) # 未删除时为null,允许为空 deletion_date = models.DateTimeField(null=True, blank=True) class Meta: db_table = 'GATEWAY'
修改后别忘了运行
python manage.py makemigrations和python manage.py migrate来更新数据库结构哦。
第二步:实现软删除逻辑(两种常用方式)
方式1:重写类视图的destroy方法(推荐,适合ModelViewSet场景)
如果你用的是ModelViewSet或者DestroyAPIView,直接重写destroy方法就能把删除改成软删除:
from rest_framework import viewsets, status from django.utils import timezone from rest_framework.response import Response from .models import Gateway from .serializers import GatewaySerializer # 假设你已经定义了对应的序列化器 class GatewayViewSet(viewsets.ModelViewSet): # 默认只返回未被软删除的记录 queryset = Gateway.objects.filter(deletion_date__isnull=True) serializer_class = GatewaySerializer def destroy(self, request, *args, **kwargs): # 获取要操作的对象 instance = self.get_object() # 设置删除时间为当前时间 instance.deletion_date = timezone.now() instance.save() return Response({"message": "芯片已标记为删除"}, status=status.HTTP_200_OK)
这样前端调用默认的DELETE路由(比如
/gateways/<pk>/)时,就会触发软删除逻辑,而不是真的删除数据库记录。
方式2:自定义函数视图(适合单独路由场景)
如果你习惯用函数视图,可以写一个专门的软删除接口:
from django.utils import timezone from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from .models import Gateway @api_view(['DELETE']) def soft_delete_gateway(request, pk): try: # 只操作未被删除的记录 gateway = Gateway.objects.get(pk=pk, deletion_date__isnull=True) gateway.deletion_date = timezone.now() gateway.save() return Response({"message": "芯片已标记为删除"}, status=status.HTTP_200_OK) except Gateway.DoesNotExist: return Response({"error": "芯片不存在或已被删除"}, status=status.HTTP_404_NOT_FOUND)
然后在urls.py中添加对应的路由:
from django.urls import path from .views import soft_delete_gateway urlpatterns = [ # 其他路由... path('gateways/<int:pk>/soft-delete/', soft_delete_gateway, name='soft-delete-gateway'), ]
第三步:序列化器的小优化
如果不需要把deletion_date返回给前端,可以在序列化器中隐藏这个字段:
from rest_framework import serializers from .models import Gateway class GatewaySerializer(serializers.ModelSerializer): class Meta: model = Gateway # 只返回需要展示给前端的字段 fields = ['id', 'gateway_chip', 'creation_date']
最后只需要让前端的删除按钮请求对应的接口路由,点击后就会触发软删除操作啦~
内容的提问来源于stack exchange,提问作者allissx
相关产品推荐
相关产品推荐

