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

Django中POST请求访问删除路由报404,GET可正常访问的问题排查

问题

点击deleteSubmit按钮通过路由saga/delete/2删除阵营时,返回404错误:

"POST /saga/delete/2/ HTTP/1.1" 404 3048
Not Found: /saga/delete/2/

但手动用GET方法访问该路由可正常访问。

相关配置代码

项目URL配置(project/urls.py)

urlpatterns = [
    path("saga/", include("saga.urls")),
    path('admin/', admin.site.urls),
]

应用URL配置(saga/urls.py)

app_name = "saga"

urlpatterns = [
    #ex: /saga/
    path("", views.index, name = "index"),
    #ex: /saga/results/1
    path("results/<int:factionId>",views.results, name = 'results'),
    #ex: /saga/edit/
    path("create/", views.create, name = 'create'),
    #ex: /saga/edit/1
    path("edit/<int:factionId>", views.edit, name = 'edit'),  
    #ex: /saga/delete/1
    path("delete/<int:factionId>", views.delete, name = 'delete')
    #ex: /saga/edit/push/?
]

表单提交JS代码

factionForm.addEventListener('submit', function(event) {
        //prevent the default form submission
        event.preventDefault(); 
        //If the Save Changes button is clicked
        if (event.submitter === saveSubmit){
            console.log("Save Changes Pressed");
            // Code to handle form submission and save changes to the database
        }

        //Otherwise if the Delete changes button is clicked
        else if(event.submitter === deleteSubmit){
            console.log("Delete Faction Pressed");
            //Attempt to send data to server
            fetch(`/saga/delete/${factionId.value}/`, {
                method: 'POST',
                headers: {
                    'X-CSRFToken': getCSRF(),
                },
            })
            //Get response from server
            .then(response => {
                if (response.ok) {
                    console.log('Faction deleted successfully');
                } else {
                    //If a problem occurred display the response
                    console.error('Error deleting faction',response);
                }
            })
            //If There is an error output it
            .catch(error => {
                console.error('Error:', error);
            });
        }

        //Otherwise if neither approved button submitted the form something went wrong
        else {
            console.log(event.submitter, "somehow submitted the form, check and correct the code near that element");
        }
    })

CSRF获取函数

function getCSRF() {
    const cookies = document.cookie.split('; ');
    for (let i = 0; i < cookies.length; i++) {
        const [name, value] = cookies[i].split('=');
        if (name === "csrfToken") {
            return decodeURIComponent(value);
        }
    }
  return null;
}

视图函数(saga/views.py)

def delete(request,factionId):
    #Get Faction To Delete
    faction = Faction.objects.filter(id = factionId)
    #If Faction Exists and Data has been posted from a form
    if faction.count() > 0 and request.method == 'POST':
        #Delete the faction
        faction.delete()
        #Return to create page on success (Will change to success message later)
        return redirect(reverse("saga:create"))
    
    #Return to home page on failure (happens currently during a Get request
    return redirect(reverse("saga:index"))    

表单定义

<form id = "factionForm" method = "post">
        {% csrf_token %}
<!-- Lots of Code -->
</form>

已尝试移除csrf_token并使用@csrf_exempt装饰器、更换csrf_token获取函数、确认CsrfViewMiddleware存在、修改URL配置,但问题未解决。


解决方案

1. 修复URL路径的斜杠匹配问题

Django的path()是严格匹配路径的,你的URL配置中delete/<int:factionId>不带末尾斜杠,但JS中fetch的URL是/saga/delete/${factionId.value}/(带末尾斜杠),导致POST请求路径无法匹配路由,返回404。

修改方法二选一:

  • 方法一:修改JS中的fetch URL,去掉末尾斜杠:
    fetch(`/saga/delete/${factionId.value}`, {
        // 其他配置不变
    })
    
  • 方法二:修改saga/urls.py中的路由,添加末尾斜杠:
    path("delete/<int:factionId>/", views.delete, name = 'delete')
    

2. 修复CSRF Token的Cookie名称

Django默认存储CSRF Token的Cookie名称是csrftoken(全小写),但你的getCSRF()函数中判断的是"csrfToken"(驼峰式),导致无法正确获取Token,即使URL匹配成功,也会触发CSRF验证失败。

修改getCSRF()函数:

function getCSRF() {
    const cookies = document.cookie.split('; ');
    for (let i = 0; i < cookies.length; i++) {
        const [name, value] = cookies[i].split('=');
        // 改为全小写的csrftoken
        if (name === "csrftoken") {
            return decodeURIComponent(value);
        }
    }
  return null;
}

3. 可选优化:使用Django的URL反向解析

为避免硬编码URL导致的路径错误,建议在模板中生成删除接口的URL,传递给JS使用:

<script>
const deleteUrl = "{% url 'saga:delete' faction.id %}";
</script>

之后在JS中直接使用deleteUrl作为fetch的地址,无需手动拼接路径。


内容的提问来源于stack exchange,提问作者Scott Field

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:05:22