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

Django项目中file input的change事件异常问题排查与解决

已解决

经@CodeThing的评论提醒,问题出在页面上存在另一个相同表单。这一情况并不明显:遇到该问题的Django开发者,请检查模板中的{% include %}标签,因为另一个包含同名元素的表单位于同一页面的模态框中。JS和Django都不会抛出相关错误,仅查看模板难以发现,需通过浏览器检查工具搜索才能找到。

核心原则:若遇到此类问题,使用检查工具查找是否存在其他相同id的元素,若有则移除,代码即可正常运行。


需求目标
  • 我有两个输入框:(1) 'file-input'文件输入框,(2) 'text-input'文本输入框
  • 希望监听'file-input'的'change'事件(即成功选择文件时),并在事件触发时将'text-input'的值设置为所选文件名。
问题现象
  1. 使用addEventListener绑定'change'事件时,事件无法触发
  2. 使用输入框的'onchange'属性时,事件可触发,但仍无法获取文件列表
上下文环境

这是一个Django项目,前端使用Bootstrap 5(无JQuery)。我尽可能使用Django Crispy Forms,但已将其从该模板中移除(排查是否因此导致问题,但并非如此)。


尝试的解决方案

我知道这本该很简单。我查看了许多类似帖子,并搭建了一个可正常运行的测试HTML脚本,确认思路无误,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>

<input type="file" name="file" id="file-input" accept=".mp3,.mp4,.mpeg,.mpga,.m4a,.wav,.webm">
<input type="text" name="text" id="text-input">

<script>
const fileInput = document.getElementById("file-input");
const textInput = document.getElementById("text-input");

console.log(fileInput);
console.log(textInput);

fileInput.addEventListener('change', () => {
    console.log('change registered');
    if (fileInput.files.length > 0) {
        console.log(fileInput.files);
        console.log(fileInput.files[0].name);
        textInput.value = fileInput.files[0].name;
    }
});
</script>
    
</body>
</html>

该测试脚本输出符合预期,运行正常:

  • input id="file-input" type="file" name="file" accept=".mp3,.mp4,.mpeg,.mpga,.m4a,.wav,.webm"
  • input id="text-input" type="text" name="text"
  • change registered
  • FileList [ File ]
  • interview.mp4*

存在问题的代码

我的Django项目模板已尽可能复刻测试脚本的结构,相关代码如下:

<form id="file-form" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <div class="my-4 px-1">
        <input type="file" name="file" id="file-input" accept=".mp3,.mp4,.mpeg,.mpga,.m4a,.wav,.webm">
    </div>
    <div class="my-3 px-1">
        <input type="text" name="text" id="text-input">
    </div>
    <button type="submit" class="btn btn-add">
        Transcribe
    </button>
    <script>
        const fileInput = document.getElementById("file-input");
        const textInput = document.getElementById("text-input");

        console.log(fileInput);
        console.log(textInput);

        fileInput.addEventListener('change', () => {
            console.log('change registered');
            if (fileInput.files.length > 0) {
                console.log(fileInput.files);
                console.log(fileInput.files[0].name);
                textInput.value = fileInput.files[0].name;
            }
        });
    </script>
</form>

但该代码输出异常,change事件未触发!

即仅输出以下内容:

  • input id="file-input" class="form-control form-control-file" type="file" name="file" required=""
  • input id="text-input" type="text" name="text"
  • 无其他输出

我尝试使用输入框的'onchange'属性修复,事件虽可触发,但fileInput.files仍为空列表,无法解决问题。

我查阅了一些Stack Overflow答案,但它们仅在测试脚本中有效,无法解决我的问题。

我是否遗漏了什么?为何测试脚本正常运行,但Django版本却不行?脚本确实在运行(可正确打印两个输入框);已排除Django Crispy Forms的影响;移除form和csrf_input后问题仍存在。我对此感到十分困惑!

恳请各位提供帮助!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:54:59