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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:22:49