如何检查上传文件是否为PDF?解决UploadFile对象不可下标错误
问题修复与PDF校验实现
错误原因分析
你触发的TypeError是因为uploadfile是你创建的UploadFile模型实例,并非可下标访问的元组或列表,所以不能用uploadfile[1]来获取文件名相关信息。
具体修改步骤
修正扩展名获取逻辑
直接从上传的文件对象(request.FILES["upload_file"])或模型实例的image字段中提取文件名,再通过os.path.splitext拆分扩展名。完善PDF格式校验
- 扩展名校验:统一转为小写,避免
.PDF这类大写扩展名被误判 - 可选文件头校验(更可靠):读取文件前几个字节,确认是否为PDF专属标识
%PDF-,防止仅修改扩展名的伪造文件
- 扩展名校验:统一转为小写,避免
修改后的完整代码
import os from django.conf import settings def post(self, request): submitted_form = ProfileForm(request.POST, request.FILES) content = '' if submitted_form.is_valid(): # 获取上传的原始文件对象 uploaded_file_obj = request.FILES["upload_file"] # 提取扩展名并标准化处理:转小写、去除开头的点号 file_extension = os.path.splitext(uploaded_file_obj.name)[1].lower().lstrip('.') # 基础扩展名校验 valid_pdf = file_extension == 'pdf' # 可选:添加文件头校验(推荐,提升安全性) if valid_pdf: uploaded_file_obj.seek(0) # 重置文件指针到起始位置 file_header = uploaded_file_obj.read(4) valid_pdf = file_header == b'%PDF' uploaded_file_obj.seek(0) # 重置指针,不影响后续保存操作 if valid_pdf: print('是PDF格式') uploadfile = UploadFile(image=uploaded_file_obj) uploadfile.save() # 注意:PDF是二进制文件,必须用'rb'模式读取 with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'rb') as f: content = f.read() print(content) else: print('不是PDF格式') # 给表单添加错误提示,告知用户格式要求 submitted_form.add_error('upload_file', '仅支持上传PDF格式文件') return render(request, "main/create_profile.html", { 'form': ProfileForm() if valid_pdf else submitted_form, "content": content }) return render(request, "main/create_profile.html", { "form": submitted_form, })
额外提示
- 读取PDF文件必须使用
'rb'模式,否则会因二进制编码问题报错。 - 文件头校验能有效拦截伪造的PDF文件,建议保留该逻辑。
- 若你的表单上传字段名称不是
upload_file,需对应修改代码中相关的字段名。
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

