You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在URL不携带<pk>时实现API删除?DRF浏览器无响应问题

问题原因及解决办法

DRF默认的Browsable API(自带网页调试界面)是为带主键的单资源详情接口设计的,它默认认为DELETE请求通过URL中的pk参数定位资源,不会自动给集合接口(比如api/barrel)的DELETE请求生成带请求体的输入表单。你点击删除按钮后,请求没有携带code字段,后端处理失败,而界面未给出明确反馈,所以看起来没反应。

下面提供两种可行的解决方法:

方法一:用序列化器让Browsable API自动生成表单

  1. 先创建一个仅用于删除验证的序列化器:
# serializers.py
from rest_framework import serializers

class BarrelDeleteSerializer(serializers.Serializer):
    code = serializers.CharField(required=True, help_text='需要删除的桶编号')
  1. 修改你的BarrelAPIView,在DELETE方法中用这个序列化器验证请求体,同时让Browsable API识别该序列化器:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Barrel
from .serializers import BarrelSerializer, BarrelDeleteSerializer

class BarrelAPIView(APIView):
    def get(self, request):
        barrels = Barrel.objects.all()
        serializer = BarrelSerializer(barrels, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = BarrelSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request):
        # 用删除专用序列化器验证请求体
        serializer = BarrelDeleteSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
        code = serializer.validated_data['code']
        try:
            barrel = Barrel.objects.get(code=code)
            barrel.delete()
            return Response({'message': '删除成功'}, status=status.HTTP_204_NO_CONTENT)
        except Barrel.DoesNotExist:
            return Response({'error': '不存在该编号的桶'}, status=status.HTTP_404_NOT_FOUND)
    
    # 让Browsable API知道DELETE请求用哪个序列化器
    def get_serializer(self, *args, **kwargs):
        if self.request.method == 'DELETE':
            return BarrelDeleteSerializer(*args, **kwargs)
        return super().get_serializer(*args, **kwargs)

修改完成后,在Browsable API中切换到DELETE方法时,界面会自动生成code字段的输入框,输入后提交就能正常触发删除逻辑。

方法二:自定义Browsable API模板添加表单

如果不想用序列化器,也可以直接修改界面模板:

  1. 在你的Django应用下创建模板目录templates/rest_framework/,新建api.html文件:
{% extends "rest_framework/base.html" %}

{% block content %}
    {{ block.super }}
    <!-- 为DELETE请求添加自定义表单 -->
    {% if request.method == 'DELETE' %}
        <div class="card mt-4">
            <div class="card-header">
                <h5>删除桶(通过编号)</h5>
            </div>
            <div class="card-body">
                <form action="" method="post">
                    {% csrf_token %}
                    <!-- 模拟DELETE请求 -->
                    <input type="hidden" name="_method" value="DELETE">
                    <div class="form-group mb-3">
                        <label for="code" class="form-label">桶编号</label>
                        <input type="text" name="code" id="code" class="form-control" required>
                    </div>
                    <button type="submit" class="btn btn-danger">执行删除</button>
                </form>
            </div>
        </div>
    {% endif %}
{% endblock %}
  1. 在项目的settings.py中配置DRF使用自定义模板:
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
    # 指定自定义模板路径
    'TEMPLATE_DIRS': ['your_app/templates'],
}

之后打开Browsable API切换到DELETE方法,就能看到自定义的删除表单,输入code后提交即可。

内容的提问来源于stack exchange,提问作者Wei Jian Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:25:19