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

Django上传文件验证后无法重定向,页面仅重载无响应如何解决?

问题:Django文件上传验证后无法重定向,页面仅重载且无日志记录
  • 文件上传验证完成后预期重定向到/t/,但实际仅重载当前页面
  • 服务器无任何日志输出,无法定位是文件未上传还是视图逻辑问题
  • 尝试AJAX提交后问题依旧,页面仍无变化或重定向(已确认urls.py配置无误)

现有代码

HTML

<form method="post" action="{% url 'transcribeSubmit' %}" enctype="multipart/form-data" >
    {% csrf_token %}
    <label for="transcribe-file" class="transcribe-file-label">
    <input id="transcribe-file" name="audio-video" type="file" accept="audio/*, video/*" hidden>
    <button class="upload" id="transcribe-submit" type="submit" >Submit</button>
</form>

JS

document.getElementById("transcribe-file").addEventListener("change", function(event){
    document.getElementById("transcribe-submit").click();
});

views.py

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_protect
from .models import TranscribedDocument
from .forms import UploadFileForm
from django.core.files.storage import FileSystemStorage

# Create your views here.

@csrf_protect
def transcribeSubmit(request):
    if request.method == 'POST':
        
        form = UploadFileForm(request.POST, request.FILES)

        try:
            if form.is_valid():
                audio_file = form.save()
                return redirect('/t/')
        except Exception as e:
            print(f"An error occurred: {e}")
            error_message = f"An error occurred: {e}"
            return JsonResponse({'error': error_message}, status=500)

    else:
        form = UploadFileForm()
        
    return render(request,'transcribe/transcribe.html', {'form': form})

forms.py

from django import forms
import mimetypes
import magic
from django.core.exceptions import ValidationError

def validate_file(file):
    # Validate if no file submitted (size = None)
    if file is None:
        raise ValidationError("No file submitted")
    else:

        #Check file size
        fileSize = file.size
        maxSize = 5242880  # 5MB in bytes (also: 5 * 1024 * 1024)
    
        if fileSize > maxSize:###test
            raise ValidationError("The maximum file size that can be uploaded is 10MB")
        else:

            try:
                # Check the file extension
                file_type = str(file.name).lower().split('.')[-1]

                #add more
                allowed_types = {
            'm4a': 'audio/mp4',
            'wav': ['audio/wav', 'audio/x-wav'],
            'mp3': 'audio/mpeg',
            'mpeg': 'video/mpeg',
            'mp4': 'video/mp4',
            'webm': 'video/webm',
            'mpga': 'audio/mpeg'
            }
                
                if file_type not in allowed_types.keys():
                    raise ValidationError(f"Unsupported file type. Allowed types are: {', '.join(accepted_types)}")

                

        # Create a magic object to check the file MIME type from content
                validator = magic.Magic(uncompress=True, mime=True)
        
        # Get the MIME type  based on content
                mime_type = validator.from_buffer(file.read(1000))#


        # Check if the guessed MIME type and content-based MIME type match
                if mime_type not in allowed_types[file_type]:
                    raise ValidationError(f"incorrect extension")
            
            except Exception as e:
                raise ValidationError(f"Validation error: {str(e)}")

class UploadFileForm(forms.Form):
    file = forms.FileField(validators=[validate_file])

问题定位与修复方案

核心错误点

  1. 表单字段名不匹配:HTML中文件输入的name是audio-video,但forms.py中字段名是file,导致表单无法获取上传文件,直接验证失败
  2. 未定义变量引用:forms.py验证函数中使用了未定义的accepted_types,应改为allowed_types.keys()
  3. Form类无save方法:UploadFileForm是普通Form类,不是ModelForm,调用form.save()会报错
  4. 验证失败无错误反馈:视图中表单验证失败后未传递错误信息到模板,导致页面重载但无提示

修正后的代码

HTML(修正字段名)

<form method="post" action="{% url 'transcribeSubmit' %}" enctype="multipart/form-data" >
    {% csrf_token %}
    <label for="transcribe-file" class="transcribe-file-label">
    <input id="transcribe-file" name="file" type="file" accept="audio/*, video/*" hidden>
    <button class="upload" id="transcribe-submit" type="submit" >Submit</button>
</form>

forms.py(修正变量+改为ModelForm)

from django import forms
import magic
from django.core.exceptions import ValidationError
from .models import TranscribedDocument

def validate_file(file):
    # 验证是否提交文件
    if not file:
        raise ValidationError("未提交文件")
    
    # 检查文件大小(5MB)
    maxSize = 5 * 1024 * 1024
    if file.size > maxSize:
        raise ValidationError("最大允许上传文件大小为5MB")
    
    try:
        # 检查文件扩展名
        file_type = str(file.name).lower().split('.')[-1]
        allowed_types = {
            'm4a': 'audio/mp4',
            'wav': ['audio/wav', 'audio/x-wav'],
            'mp3': 'audio/mpeg',
            'mpeg': 'video/mpeg',
            'mp4': 'video/mp4',
            'webm': 'video/webm',
            'mpga': 'audio/mpeg'
        }
        
        if file_type not in allowed_types:
            raise ValidationError(f"不支持的文件类型,允许的类型:{', '.join(allowed_types.keys())}")
        
        # 检查文件内容MIME类型
        validator = magic.Magic(uncompress=True, mime=True)
        mime_type = validator.from_buffer(file.read(1000))
        
        # 统一格式为列表方便判断
        expected_mimes = allowed_types[file_type]
        if not isinstance(expected_mimes, list):
            expected_mimes = [expected_mimes]
        
        if mime_type not in expected_mimes:
            raise ValidationError("文件扩展名与实际内容不匹配")
            
    except Exception as e:
        raise ValidationError(f"验证错误:{str(e)}")

# 改为ModelForm以支持save()方法
class UploadFileForm(forms.ModelForm):
    class Meta:
        model = TranscribedDocument
        fields = ['file']
    file = forms.FileField(validators=[validate_file])

views.py(完善错误处理)

from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_protect
from .forms import UploadFileForm

@csrf_protect
def transcribeSubmit(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        try:
            if form.is_valid():
                form.save()
                return redirect('/t/')
        except Exception as e:
            print(f"错误:{e}")
            return JsonResponse({'error': str(e)}, status=500)
        # 验证失败时带着错误返回页面
        return render(request,'transcribe/transcribe.html', {'form': form})
    else:
        form = UploadFileForm()
    return render(request,'transcribe/transcribe.html', {'form': form})

调试补充建议

  • 在模板中添加错误信息展示,方便排查问题:
{% if form.errors %}
    <div class="error-messages">
        {% for field in form %}
            {% for error in field.errors %}
                <p>{{ error }}</p>
            {% endfor %}
        {% endfor %}
        {% for error in form.non_field_errors %}
            <p>{{ error }}</p>
        {% endfor %}
    </div>
{% endif %}
  • 开启Django调试模式(DEBUG=True),页面会显示详细错误栈
  • 查看浏览器开发者工具的Network标签,检查请求状态码与响应内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:35:56