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

Django中POST请求更新保存赛事字典的JSON格式问题

解决Django+JS赛事对阵图的JSON格式转换问题

我来帮你一步步排查这个JSON相关的问题,核心原因就是前后端在JSON序列化/反序列化环节不匹配,导致了前端语法错误和后端解码失败。

一、先解决前端$.post的语法错误

你遇到的Uncaught SyntaxError: Invalid or unexpected token,大概率是因为前端没有正确构造标准JSON字符串就发送请求,或者没有告诉后端你发的是JSON数据。

正确的前端写法

首先,确保从Django模板获取赛事数据时用安全的方式,推荐用Django的json_script标签(避免XSS和格式混乱):

<!-- 在模板中添加这行,把Python字典转成安全的JSON字符串嵌入页面 -->
{{ bracket|json_script:"bracket-data" }}

然后在JS里正确读取并发送数据:

// 从页面获取赛事数据并转成JS对象
const rawBracket = document.getElementById('bracket-data').textContent;
const bracketData = JSON.parse(rawBracket);

// 假设你已经修改了bracketData,现在提交更新
$.post({
  url: '/update_bracket/',
  contentType: 'application/json', // 关键:告诉后端这是JSON格式
  data: JSON.stringify(bracketData), // 把JS对象转成标准JSON字符串(必须双引号)
  success: function() {
    window.location.href = '/bracket/'; // 重定向回对阵图页面
  },
  error: function(xhr) {
    console.error('更新失败:', xhr.responseText);
  }
});

为什么之前会报错?

  • 如果直接传递JS对象而不用JSON.stringify,jQuery会把它转成表单格式(key=value&...),不是JSON
  • 如果手动拼接JSON字符串用了单引号(比如'{ "key": 'value' }'),这不符合JSON标准(必须双引号包裹属性名和字符串值)

二、修复后端update_bracket视图的JSONDecodeError

前端正确发送JSON后,后端不能再用request.POST读取数据(request.POST是用来处理表单的),要直接读取请求体的原始JSON字符串:

import json
from django.shortcuts import redirect
from django.http import JsonResponse
from .models import Employee

def update_bracket(request):
    if request.method != 'POST':
        return JsonResponse({'error': '仅接受POST请求'}, status=400)
    
    try:
        # 从请求体读取原始JSON并转成Python字典
        bracket_data = json.loads(request.body)
        
        # 保存到Employee的JSONField(直接存字典就行,Django会自动序列化)
        # 这里替换成你实际获取Employee对象的逻辑
        employee = Employee.objects.get(user=request.user)
        employee.bracket = bracket_data
        employee.save()
        
        return redirect('bracket') # 重定向回对阵图视图
    except json.JSONDecodeError as e:
        return JsonResponse({'error': f'JSON解码失败: {str(e)}'}, status=400)
    except Employee.DoesNotExist:
        return JsonResponse({'error': '未找到对应员工'}, status=404)

注意:Django的JSONField本身支持直接存储Python字典,不需要你手动转成JSON字符串,它会自动处理序列化和反序列化。

三、检查Tournament类生成的字典格式

还要确保你的Tournament类生成的字典是JSON可序列化的,不能包含Python专属类型:

  • 比如datetime对象要转成ISO字符串(date.isoformat())
  • Decimal类型要转成float或字符串
  • 不能有自定义类实例、函数这类无法序列化的对象

示例修复:

class Tournament:
    def generate_bracket(self):
        bracket = {
            "rounds": [
                {
                    "matches": [
                        {
                            "team1": "Team A",
                            "team2": "Team B",
                            "match_date": self.match_date.isoformat(), # 转成JSON支持的字符串
                            "score": {"team1": 2, "team2": 1}
                        }
                    ]
                }
            ]
        }
        return bracket

四、常见坑点总结

  1. 前端必须用JSON.stringify()转成标准JSON,同时设置contentType: 'application/json'
  2. 后端必须读取request.body,而不是request.POST
  3. 确保传递的数据里没有Python专属类型,全部是JSON支持的类型(字符串、数字、列表、字典、布尔值、null)
  4. 模板传递JSON用json_script标签,比直接{{ bracket|safe }}更安全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:27:30