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

如何在现代Django中打包单个文件夹内多文件并发送至浏览器

Django 多文件压缩包下载实用方案

核心逻辑

直接在内存中生成压缩包,通过Django响应返回给浏览器,全程不用在服务器创建临时文件,既省磁盘空间又高效。

基础实现代码(适合中小文件)

import io
import zipfile
from django.http import HttpResponse
from django.conf import settings

def download_multiple_files_as_zip(request):
    # 替换成你要压缩的文件路径列表,这里以媒体目录下的文件为例
    target_files = [
        settings.MEDIA_ROOT / "report.pdf",
        settings.MEDIA_ROOT / "screenshot.png",
        settings.MEDIA_ROOT / "data.csv"
    ]

    # 初始化内存字节流,用来存压缩包数据
    zip_buffer = io.BytesIO()

    # 创建压缩包,ZIP_DEFLATED是带压缩的模式,要速度的话换ZIP_STORED(无压缩)
    with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_obj:
        for file_path in target_files:
            # 先判断文件存在再添加,避免报错
            if file_path.exists():
                # arcname是压缩包里显示的文件名,这里用原文件名
                zip_obj.write(file_path, arcname=file_path.name)

    # 把字节流指针移到开头,不然浏览器读不到内容
    zip_buffer.seek(0)

    # 构造响应
    response = HttpResponse(zip_buffer, content_type="application/zip")
    # 指定下载的文件名,浏览器会自动触发下载
    response["Content-Disposition"] = 'attachment; filename="download_files.zip"'

    return response

大文件场景优化

如果要压缩的文件总大小很大,用内存处理容易爆内存,换成流式响应:

import io
import zipfile
from django.http import StreamingHttpResponse
from django.conf import settings

def stream_large_files_as_zip(request):
    target_files = [
        settings.MEDIA_ROOT / "big_file1.iso",
        settings.MEDIA_ROOT / "big_file2.mp4"
    ]

    def zip_stream_generator():
        with io.BytesIO() as chunk_buffer:
            with zipfile.ZipFile(chunk_buffer, "w", zipfile.ZIP_DEFLATED) as zip_obj:
                for file_path in target_files:
                    if file_path.exists():
                        zip_obj.write(file_path, arcname=file_path.name)
                        # 把当前chunk的内容返回给浏览器
                        chunk_buffer.seek(0)
                        yield chunk_buffer.read()
                        # 清空buffer准备下一个文件
                        chunk_buffer.seek(0)
                        chunk_buffer.truncate()

    response = StreamingHttpResponse(zip_stream_generator(), content_type="application/zip")
    response["Content-Disposition"] = 'attachment; filename="large_files.zip"'
    return response

注意点

  • 一定要检查文件是否存在,不然会抛出文件不存在的异常
  • 内容类型application/zip必须正确,不然浏览器可能不会识别为压缩包
  • 如果是用户上传的文件,要做好权限校验,避免泄露敏感文件

内容的提问来源于stack exchange,提问作者Swantewit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:05:18