Django订单状态更新遇405错误:点击按钮无法修改Pending状态
解决Django订单审批/拒绝功能的405错误问题
问题背景
开发店主面板的订单审批/拒绝功能,Django admin中可正常修改订单状态,但前端点击按钮时出现405错误,无法将Pending状态改为Approved或Rejected。
错误原因
- 视图函数仅从
request.GET获取参数,但AJAX请求使用POST方法,导致请求方法不匹配 - AJAX请求的URL与视图路由不对应(原JS使用两个不同URL,但实际只有一个处理视图)
- 原JS尝试从按钮的
data-id属性获取ID,但模板中未设置该属性 - 模板中按钮为
submit类型,未完全阻止默认表单提交行为
修正方案
1. 更新视图函数(views.py)
修改视图以支持POST请求,从request.POST获取参数,并处理请求方法校验:
from django.http import HttpRequest, JsonResponse from django.shortcuts import get_object_or_404 from .models import TimeSlice def update_appointment_status(request: HttpRequest): if request.method != 'POST': return JsonResponse({'success': False, 'error': '仅支持POST请求'}, status=405) timeslice_id = request.POST.get('timeslice_id') status = request.POST.get('status') timeslice = get_object_or_404(TimeSlice, id=timeslice_id) if status == 'approve': timeslice.approve() elif status == 'refuse': timeslice.refuse() return JsonResponse({'success': True})
2. 配置路由(urls.py)
将视图映射到统一的URL:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('update-appointment-status/', views.update_appointment_status, name='update_appointment_status'), ]
3. 修正AJAX逻辑(JS代码)
统一请求URL,添加status参数,从表单隐藏字段获取订单ID,并优化按钮事件:
$(document).ready(function() { // 审批按钮事件 $('.approve-btn').click(function(event) { event.preventDefault(); const timesliceId = $(this).closest('form').find('input[name="timeslice_id"]').val(); $.ajax({ url: '/update-appointment-status/', type: 'POST', data: { 'timeslice_id': timesliceId, 'status': 'approve', 'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val() }, success: () => { alert('预约已通过'); location.reload(); }, error: (xhr, status, error) => { alert('错误: ' + error); } }); }); // 拒绝按钮事件 $('.refuse-btn').click(function(event) { event.preventDefault(); const timesliceId = $(this).closest('form').find('input[name="timeslice_id"]').val(); $.ajax({ url: '/update-appointment-status/', type: 'POST', data: { 'timeslice_id': timesliceId, 'status': 'refuse', 'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val() }, success: () => { alert('预约已拒绝'); location.reload(); }, error: (xhr, status, error) => { alert('错误: ' + error); } }); }); });
4. 调整模板代码
将按钮类型改为button避免默认提交,保留必要的隐藏字段和CSRF令牌:
{% for slice in time_slices %} {% if slice.business_line == barber %} <li> {{ slice.start_time }} - {{ slice.end_time }} <p>状态: {{ slice.get_appointment_state_display }}</p> <form> {% csrf_token %} <input type="hidden" name="timeslice_id" value="{{ slice.id }}"> <button type="button" class="approve-btn">通过</button> <button type="button" class="refuse-btn">拒绝</button> </form> </li> {% endif %} {% endfor %}
内容的提问来源于stack exchange,提问作者Aetoox
相关产品推荐
相关产品推荐

