如何在Django中压缩多上传文件并保存至数据库?附报错解决
问题解决与实现方案
一、报错原因分析
你遇到的FileNotFoundError是因为zipfile.ZipFile.write()方法的作用是将本地已存在的文件添加到压缩包,它要求第一个参数是本地文件的路径。但你传入的uploadedFile.name只是上传文件的原始文件名,并非服务器本地的文件路径,所以系统找不到对应的文件。
二、修改后的完整实现代码
1. 模型层(models.py)
确保你的File模型使用FileField字段,并配置存储路径:
from django.db import models class File(models.Model): # 配置文件保存到media/zips目录下 file = models.FileField(upload_to='zips/') created_at = models.DateTimeField(auto_now_add=True)
2. 视图层(views.py)
修改为内存中生成压缩包,避免本地临时文件,同时完成数据库保存:
import zipfile from io import BytesIO from django.shortcuts import render, HttpResponse from django.core.files import File as DjangoFile from .models import File def index(request): if request.method == 'GET': return render(request, 'index.html') elif request.method == 'POST': uploaded_files = request.FILES.getlist('files') # 用BytesIO在内存中创建压缩包,无需生成本地文件 zip_buffer = BytesIO() # 使用ZIP_DEFLATED启用压缩,不写的话是无压缩的zip with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file: for uploaded_file in uploaded_files: # 用writestr直接写入内存中的文件内容,第一个参数是压缩包内的文件名 zip_file.writestr(uploaded_file.name, uploaded_file.read()) # 将文件指针移到开头,否则Django无法读取到压缩包内容 zip_buffer.seek(0) # 把内存中的压缩包包装成Django可识别的File对象 django_zip_file = DjangoFile(zip_buffer, name='compressed_files.zip') # 保存到数据库 File.objects.create(file=django_zip_file) return HttpResponse('文件压缩并保存成功')
三、关键注意事项
- 必须使用
zipfile.ZipFile.writestr()替代write():前者支持直接写入字节数据,适配上传的内存文件对象。 - 内存操作后需重置指针:使用
zip_buffer.seek(0)将文件指针移到开头,否则读取时会从文件末尾开始,获取不到内容。 - 配置媒体文件路径:确保Django的
MEDIA_ROOT和MEDIA_URL已正确配置,否则无法正常访问保存的压缩文件。
内容的提问来源于stack exchange,提问作者Partho Debnath
相关产品推荐
相关产品推荐

