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

Django通过AJAX读取上传文件渲染表格报MultiValueDictKeyError如何解决

问题原因
  • 发起的AJAX请求未携带上传的文件数据,也未传递Django要求的CSRF校验令牌
  • 提交按钮未放在form标签内,无法正常关联表单内的文件字段
  • fetch请求未构造FormData对象传递文件,导致后端request.FILES为空,触发MultiValueDictKeyError报错
  • JS代码中使用了未定义的tableRow1变量,即使接口返回正常也无法渲染表格
实现方案

方案1:表单直接提交跳转新页面(实现最简单,稳定性高)

步骤1:修改前端上传模板

将提交按钮放入form标签内,指定表单提交地址为table对应的路由:

<form method="post" enctype="multipart/form-data" action="{% url 'table' %}">
    {% csrf_token %}
    {{ form.as_p }}  
    <button type="submit" id="upload">Upload file</button>          
</form>

步骤2:修改后端table视图

校验表单后渲染表格页面:

from django.shortcuts import render, redirect
from .forms import UploadFileForm

def table(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            table_html = file_to_HTML(form.cleaned_data['file'])
            return render(request, 'table.html', {'table_html': table_html})
    # 表单校验失败跳转回上传页
    return redirect('upload')

步骤3:新建表格展示模板table.html

直接渲染生成的表格内容:

<!DOCTYPE html>
<html>
<head>
    <title>文件解析结果</title>
</head>
<body>
    <!-- 加safe过滤器确保HTML内容被正常渲染,不会被转义 -->
    {{ table_html|safe }}
</body>
</html>

方案2:AJAX无刷新渲染表格

步骤1:修改前端模板

保留原有表单结构,将按钮放入form内,新增表格渲染容器:

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}  
    <button type="button" id="upload">Upload file</button>          
</form>
<!-- 预留表格渲染容器 -->
<div id="table"></div>

步骤2:修改前端AJAX代码

构造FormData传递文件和CSRF令牌:

var uploadBtn = document.getElementById("upload");
var form = document.querySelector('form');

uploadBtn.addEventListener("click", function(e){
    e.preventDefault();
    const url = "{% url 'table' %}";
    const formData = new FormData(form);

    fetch(url, {
        method: 'POST',
        body: formData,
        headers: {
            'X-CSRFToken': document.querySelector('[name="csrfmiddlewaretoken"]').value
        }
    })
    .then(response => response.json())
    .then(function(data){
        if (data.tableHTML) {
            document.getElementById('table').innerHTML = data.tableHTML;
        } else {
            alert(data.error || '文件解析失败');
        }
    })
    .catch(err => console.error('请求异常:', err))
})

步骤3:修改后端table视图

增加表单校验,返回结构化响应:

from django.http import JsonResponse
from .forms import UploadFileForm

def table(request):
    if request.method != 'POST':
        return JsonResponse({'error': '请求方法不支持'}, status=405)
    
    form = UploadFileForm(request.POST, request.FILES)
    if not form.is_valid():
        return JsonResponse({'error': '表单校验失败,请检查上传文件'}, status=400)
    
    table_html = file_to_HTML(form.cleaned_data['file'])
    return JsonResponse({"tableHTML": table_html})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:09:03