django 中 javascript 发起的 delete 请求返回 404,通常并非路由或视图逻辑错误,而是前端 url 构造不当——尤其容易因多余斜杠或协议/路径前缀导致匹配失败。本文直击该高频陷阱,详解正确写法与完整防护实践。
django
中 javascript 发起的 delete 请求返回 404,通常并非路由或视图逻辑错误,而是前端 url 构造不当——尤其容易因多余斜杠或协议/路径前缀导致匹配失败。本文直击该高频陷阱,详解正确写法与完整防护实践。
在 Django 项目中,通过 JavaScript(如 fetch)向后端发送 DELETE 请求时,看似配置无误却持续报 Not Found: /delete_document/7/,终端显示 404 状态码,这是典型的
URL 路径解析失配
问题。根本原因往往不在 Python 侧(views.py 和 urls.py 逻辑通常是正确的),而在于前端构造的请求地址未被 Django URL 路由系统识别。
? 问题定位:URL 字符串中的隐藏陷阱
观察原代码中的 fetch 调用:
此处使用了
绝对路径语法
(以 / 开头),本意是访问根路径下的 delete_document/7/。但若当前页面 URL 并非部署在站点根目录(例如实际访问地址为 https://example.com/advice/),浏览器会将 /delete_document/7/ 解析为 https://example.com/delete_document/7/ —— 而 Django 的 urls.py 仅在 advice 应用命名空间下注册了该路径,
上级 URLconf 并未包含 delete_document/ 的全局路由
,因此必然 404。
更隐蔽的是:即使部署在根路径,某些开发服务器(如 Django runserver 配合反向代理)也可能因路径规范化规则导致 /delete_document/7//(结尾双斜杠)或 /delete_document//7/(ID 前多斜杠)等非法路径,同样触发 404。
✅ 正确做法是
使用相对路径,且确保与 Django 命名 URL 完全对齐
:
⚠️ 注意:delete_document/${id}/ 是相对路径,浏览器会将其拼接到当前页面 URL 的末尾。例如当前页为 https://localhost:8000/advice/,则实际请求地址为 https://localhost:8000/advice/delete_document/7/ —— 这恰好匹配 urls.py 中定义的 path('delete_document//', ...)。
Python 网站开发之Django环境搭建 WORD版
本文档主要讲述的是Python 网站开发之Django环境搭建;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
✅ 完整可运行修复方案
1. 前端 JavaScript(修正 + 增强健壮性)
2. 后端保障(推荐补充)
虽然原 views.py 逻辑正确,但为提升健壮性,建议显式处理 CSRF(@csrf_exempt ❌ 不推荐)并增加日志:
同时确认 settings.py 中已启用 django.middleware.csrf.CsrfViewMiddleware(默认开启)。
3. 路由验证(关键!)
确保 advice/urls.py 已被主 urls.py 正确包含,并指定命名空间:
这样 delete_document/7/ 才会在 /advice/ 下被正确捕获。
? 总结:三个必须检查项
✅
URL 字符串不要以 / 开头
(除非你明确需要根路径,且主 URLconf 已配置);
✅
确保前端请求路径与 urls.py 中 path() 的 pattern 完全一致
(包括结尾斜杠、参数占位符格式);
✅
验证命名空间是否在主 urls.py 中正确 include(),且路径前缀匹配
。
一个微小的 / 符号,足以让整个 DELETE 流程静默失败。调试时优先检查浏览器开发者工具 Network 标签页中实际发出的请求 URL,与 Django 日志中的 Not Found: 路径逐字符比对——90% 的同类问题由此定位并解决。
fetch(`/delete_document/${selectedDocumentId}/`, { method: 'DELETE', ... })// ✅ 推荐:直接使用相对路径(不以 / 开头),依赖当前页面上下文
fetch(`delete_document/${selectedDocumentId}/`, {
method: 'DELETE',
headers: {
'X-CSRFToken': document.querySelector('[name="csrfmiddlewaretoken"]').value,
'Content-Type': 'application/json',
},
});# views.py
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
@csrf_protect
@require_http_methods(['DELETE'])
def delete_document(request, document_id):
document = get_object_or_404(Document, pk=document_id)
document.delete()
return JsonResponse({'message': 'Document deleted successfully'}, status=204)# 主 urls.py
from django.urls import path, include
urlpatterns = [
path('advice/', include('advice.urls', namespace='advice')),
# ...
]