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

React+Django Todo项批量更新(带复选框)500错误排查求助

React + Django Todo列表更新功能500内部服务器错误排查

我用React做前端、Django做后端实现Todo列表的更新功能,每个Todo项带复选框标记完成状态。点击「Save」按钮时,通过PUT请求把更新后的状态发给后端,但一直报500内部服务器错误,无法完成更新。

React触发PUT请求的代码(handleSave函数)

const handleSave = async (e) => {
  e.preventDefault();
  console.log('handleSave called');

  const updatedItems = items.map((item) => {
    const checkbox = e.target[`c${item.id}`];
    console.log(`Processing item id ${item.id}, checkbox value:`, checkbox?.checked);
    return {
      id: item.id,
      todolist: 1,
      text: item.text,
      complete: checkbox ? checkbox.checked : false,
      duration: item.duration,
    };
  });

  try {
    console.log('Payload to send:', updatedItems);
    const response = await axios.put(
      `${import.meta.env.VITE_API_URL}/todo-items/1`, // Update the endpoint if needed
      updatedItems,
      {
        headers: { 'Content-Type': 'application/json' }, // Set proper headers
      }
    );
    console.log('Items updated successfully:', response.data);
  } catch (error) {
    console.error('Error updating items:', error.message, error.response?.data);
  }
};

Django处理请求的视图代码

@api_view(['GET', 'PUT'])
def todo_items(request, id):
    try:
        ls = ToDoList.objects.get(id=id)
    except ToDoList.DoesNotExist:
        return Response({"error": "List not found"}, status=404)

    if request.method == 'GET':
        incomplete_items = ls.item_set.filter(complete=False)
        complete_items = ls.item_set.filter(complete=True)
        items = incomplete_items.union(complete_items, all=True)
        serializer = ItemSerializer(items, many=True)
        return Response(serializer.data)

    if request.method == 'PUT':
        if not isinstance(request.data, list):
            return Response({"error": "Invalid data format, expected a list."}, status=400)

        errors = []
        for item_data in request.data:
            try:
                item = Item.objects.get(id=item_data["id"])
                item.complete = item_data["complete"]
                item.save()
            except ObjectDoesNotExist:
                errors.append({"id": item_data["id"], "error": "Item not found."})
            except KeyError:
                errors.append({"id": item_data.get("id", None), "error": "Missing fields."})

        if errors:
            return Response({"message": "Partial update completed with errors.", "errors": errors}, status=207)

        return Response({"message": "Items updated successfully!"})

发送的Payload格式

[
  {id: 1, todolist: 1, text: 'respond to emails', complete: false, duration: '02:00:00'},
  {id: 2, todolist: 1, text: 'wash the dishes', complete: false, duration: '00:30:00'},
  {id: 3, todolist: 1, text: 'finish chemistry homework', complete: false, duration: '03:00:00'},
  {id: 4, todolist: 1, text: 'set the table', complete: true, duration: '00:05:00'},
  {id: 5, todolist: 1, text: 'clean the table', complete: true, duration: '00:05:00'},
  {id: 7, todolist: 1, text: 'eat the oranges', complete: true, duration: '03:00:00'}
]

长度:6

前端错误信息

PUT http://127.0.0.1:8000/api/todo-items/1 500 (Internal Server Error)
dispatchXhrRequest @ axios.js?v=48ceec0d:1653
xhr @ axios.js?v=48ceec0d:1533
dispatchRequest @ axios.js?v=48ceec0d:2008
_request @ axios.js?v=48ceec0d:2223
request @ axios.js?v=48ceec0d:2120
httpMethod @ axios.js?v=48ceec0d:2252
wrap @ axios.js?v=48ceec0d:8
handleSave @ App.jsx:46
processDispatchQueue @ react-dom_client.js?v=48ceec0d:11577
(anonymous) @ react-dom_client.js?v=48ceec0d:11988
batchedUpdates$1 @ react-dom_client.js?v=48ceec0d:2539
dispatchEventForPluginEventSystem @ react-dom_client.js?v=48ceec0d:11683
dispatchEvent @ react-dom_client.js?v=48ceec0d:14608
dispatchDiscreteEvent @ react-dom_client.js?v=48ceec0d:14589
App.jsx:55 Error updating items: Request failed with status code 500

排查步骤及解决办法

1. 查看Django后端日志(最关键)

前端的500错误仅说明服务器内部出错,具体原因需要看Django控制台的日志输出。启动Django服务的终端窗口会打印详细错误堆栈,比如未导入的模块、数据库操作异常等。

2. 检查ObjectDoesNotExist的导入

视图代码中使用了except ObjectDoesNotExist,但如果未在文件顶部导入该异常类,会直接触发500错误。解决方法:
在视图文件开头添加:

from django.core.exceptions import ObjectDoesNotExist

3. 捕获未处理的通用异常

当前代码仅捕获ObjectDoesNotExist和KeyError,若有其他异常(如数据库连接问题、字段类型不匹配)会直接导致500。修改循环中的异常捕获逻辑:

try:
    item = Item.objects.get(id=item_data["id"])
    item.complete = item_data["complete"]
    item.save()
except ObjectDoesNotExist:
    errors.append({"id": item_data["id"], "error": "Item not found."})
except KeyError:
    errors.append({"id": item_data.get("id", None), "error": "Missing fields."})
except Exception as e:
    errors.append({"id": item_data.get("id", None), "error": str(e)})

这样所有异常都会被捕获并返回给前端,方便排查。

4. 验证Item模型字段类型

检查Item模型中的complete字段是否定义为BooleanField,确保和前端传递的布尔值类型匹配:

class Item(models.Model):
    # 其他字段
    complete = models.BooleanField(default=False)

5. 测试单个Item更新

先构造仅包含一个Item的Payload发送PUT请求,确认单个更新是否正常,逐步排查是否是特定Item的数据导致的错误。

6. 检查URL路由映射

确认Django的URLconf中,/api/todo-items/<int:id>/是否正确映射到todo_items视图函数,避免路由参数不匹配导致的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:27:35