Django中Bootstrap模态框删除对象的404及请求方式问题修复
问题修复方案
核心问题
点击删除按钮后出现两个关键错误:
- URL路径错误:实际请求
http://127.0.0.1:8000/food/foodIndex/1/delete,但你的Django路由配置的是food/<int:id>/foodDelete/ - 请求方法错误:表单默认使用
GET请求,不符合Django对修改操作的要求,且缺少必需的CSRF令牌
分步修复
1. 修正JavaScript中的表单Action路径
当前JS代码设置的相对路径会基于当前页面(food/foodIndex/)拼接,导致URL错误。直接生成绝对路径匹配路由:
const deleteModal = document.getElementById('modal-delete'); deleteModal.addEventListener('show.bs.modal', event => { const button = event.relatedTarget; const foodName = button.getAttribute('data-bs-foodname'); const foodId = button.getAttribute('data-bs-foodid'); const modalBody = deleteModal.querySelector('.modal-body'); const modalForm = deleteModal.querySelector('form'); modalBody.textContent = `Confirm deletion of ${foodName}`; // 生成匹配路由的绝对路径 modalForm.setAttribute('action', `/food/${foodId}/foodDelete/`); });
2. 修复表单的请求方法与CSRF令牌
Django要求修改数据的请求必须用POST,且必须包含CSRF令牌防止跨站请求伪造:
<div id="modal-delete" class="modal fade" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Delete food item</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"></div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <!-- 添加POST方法和CSRF令牌 --> <form method="POST"> {% csrf_token %} <button id='food-delete' class="btn btn-warning" type="submit">Delete</button> </form> </div> </div> </div> </div>
3. 确保视图函数只处理POST请求
修改foodDelete视图,仅响应POST请求完成删除,GET请求直接重定向回列表页:
# food/views.py from django.shortcuts import get_object_or_404, redirect from .models import Food def foodDelete(request, id): food_item = get_object_or_404(Food, id=id) if request.method == 'POST': food_item.delete() return redirect('food:foodIndex') # 拦截GET请求,避免误操作 return redirect('food:foodIndex')
4. 验证URL路由配置
你的现有URL配置是正确的,确保name="foodDelete"与代码中引用的名称一致:
# food/urls.py urlpatterns = [ path('foodIndex/', views.foodIndex, name="foodIndex"), path('<int:id>/edit/', views.foodEdit, name="foodEdit"), path('<int:id>/foodDelete/', views.foodDelete, name = "foodDelete") ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
内容的提问来源于stack exchange,提问作者geoB
相关产品推荐
相关产品推荐

