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])
问题定位与修复方案
核心错误点
- 表单字段名不匹配:HTML中文件输入的
name是audio-video,但forms.py中字段名是file,导致表单无法获取上传文件,直接验证失败 - 未定义变量引用:forms.py验证函数中使用了未定义的
accepted_types,应改为allowed_types.keys() - Form类无save方法:UploadFileForm是普通Form类,不是ModelForm,调用
form.save()会报错 - 验证失败无错误反馈:视图中表单验证失败后未传递错误信息到模板,导致页面重载但无提示
修正后的代码
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
相关产品推荐
相关产品推荐

