调用form.is_valid()后CSV文件无法访问/内容为空的问题求助
问题概述
在Django中实现CSV文件上传验证时,通过检查预期表头是否存在来验证文件有效性,但调用form.is_valid()后,再次读取上传的文件会返回空列表,无任何错误提示。绕过form.is_valid()则程序正常运行,但失去验证功能。
核心原因
上传的文件对象(InMemoryUploadedFile或TemporaryUploadedFile)属于类文件对象,读取操作会让文件指针移动到末尾。你的验证器csvPackingNoteValidator中已经调用了csv_file.read()消耗了文件内容,后续视图中再次执行request.FILES['csv_upload'].read()时,指针已在末尾,自然读取不到内容。
解决方法
方法1:验证器中读取后重置文件指针
在验证器读取文件内容后,将文件指针重置到开头,确保后续视图能再次读取文件:
def csvPackingNoteValidator(csv_file): # 读取文件内容 file_content = csv_file.read().decode('utf-8') # 重置文件指针至起始位置 csv_file.seek(0) packing_list = csv.DictReader(io.StringIO(file_content)) required_headers = { 'Branch', 'Carton', 'Delivered', 'SKU', 'PLU', 'Supplier Bar Code', 'Description', 'Size', 'Product Type' } if not required_headers.issubset(packing_list.fieldnames): raise ValidationError("Invalid file, select correct report")
方法2:视图中提前读取并缓存文件内容
在初始化表单前,先读取文件内容并保存,同时重置指针让表单验证可以正常读取:
@login_required @permission_required('products.report_upload', raise_exception=True) def uploadPackingNotesView(request): if request.method == "POST": csv_upload = request.FILES['csv_upload'] # 提前读取文件内容并缓存 file_content = csv_upload.read().decode('utf-8') # 重置指针,确保表单验证能读取文件 csv_upload.seek(0) form = UploadPackingNotesForm(request.POST, request.FILES) if form.is_valid(): reader = csv.DictReader(io.StringIO(file_content)) packing_list = list(reader) parsePackingNotes.delay(packing_list) return HttpResponseRedirect(reverse_lazy('product-csv-upload-successful')) else: form = UploadPackingNotesForm() return render(request, 'products/upload-packing-notes.html', {'form': form})
内容的提问来源于stack exchange,提问作者Petchalxande
相关产品推荐
相关产品推荐

