Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >聊点Python:在Django中利用zipfile,StringIO等库生成下载的文件​

聊点Python:在Django中利用zipfile,StringIO等库生成下载的文件​

作者头像
用户8554325
发布于 2023-03-10 12:03:54
发布于 2023-03-10 12:03:54
1.9K00
代码可运行
举报
文章被收录于专栏:热度技术热度技术
运行总次数:0
代码可运行

最近在django中要用到文件下载的功能,通过查找,发现以下几种方式,就收集在一起,供日后方便查找。

第一种方式:创建一个临时文件。可以节省了大量的内存。当你有多个或两个用户并发时,你会发现节省内存是非常非常重要的。

你可以写入一个StringIO(from io import StringIO)对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())

第二种方式,将文件打包成一个文件,下载的方式,需要设置Content-Disposition

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from django.http import HttpResponse
from wsgiref.util import FileWrapper

# generate the file
response = HttpResponse(FileWrapper(myfile.getvalue()), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response

当然,以上的方式对付小文件下载还是ok,因为都是读入到内存中,但如果某个文件特别大,就不能使用这种方式,那就应该采用另外一种方式,下面就是展示一下,在Django中的大文件下载如何写代码实现。如果文件非常大时,最简单的办法就是使用静态文件服务器,比如Apache或者Nginx服务器来处理下载。不过有时候,我们需要对用户的权限做一下限定,或者不想向用户暴露文件的真实地址,或者这个大内容是临时生成的(比如临时将多个文件合并而成的),这时就不能使用静态文件服务器了。

我们在django view中,需要用StreamingHttpResponse这两个类。完整的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from django.http import StreamingHttpResponse
def big_file_download(request):
  # do something...
  def file_iterator(file_name, chunk_size=512):
    with open(file_name) as f:
      while True:
        c = f.read(chunk_size)
        if c:
          yield c
        else:
          break

  the_file_name = "big_file.pdf"
  response = StreamingHttpResponse(file_iterator(the_file_name))
  response['Content-Type'] = 'application/octet-stream'
  response['Content-Disposition'] = 'attachment;filename="{0}"'.format(the_file_name)
  return response

另外,给大家介绍一种使用zipstream库实现下载的功能,直接上代码,如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ZipUtilities(object):
    """
    打包文件成zip格式的工具类

    使用方式

    >>> utilities = ZipUtilities()
    >>> for file_obj in file_objs:
    >>>    tmp_dl_path = os.path.join(path_to, filename)
    >>> utilities.to_zip(tmp_dl_path, filename)
    >>> utilities.close()
    >>> response = StreamingHttpResponse(utilities.zip_file, content_type='application/zip')
    >>> response['Content-Disposition'] = 'attachment;filename="{0}"'.format("下载.zip")
    """
    zip_file = None

    def __init__(self):
        self.zip_file = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED)

    def to_zip(self, file, name):
        if os.path.isfile(file):
            self.zip_file.write(file, arcname=os.path.basename(file))
        else:
            self.add_folder_to_zip(file, name)

    def add_folder_to_zip(self, folder, name):
        for file in os.listdir(folder):
            full_path = os.path.join(folder, file)
            if os.path.isfile(full_path):
                self.zip_file.write(full_path, arcname=os.path.join(name, os.path.basename(full_path)))
            elif os.path.isdir(full_path):
                self.add_folder_to_zip(full_path, os.path.join(name, os.path.basename(full_path)))

    def close(self):
        if self.zip_file:
            self.zip_file.close()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 聊聊电商业务与技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
16.Django学习之文件上传和下载
更新上传了的文件(注意,只是会更新数据库中那个字段保存的文件的路径,但是之前上传的文件是不会被自动删除的,需要我们自行再写逻辑来删除之前上传错的或者需要被覆盖的文件。还有就是如果上传的文件名称是相同的那么你会发现数据库中这个字段的路径后面的文件名称会出现一个乱起八糟的随机字符串,这是因为上传的文件名称冲突了,django为了解决这个冲突,给你改了一下你的文件名称。)
changxin7
2019/12/12
1.2K0
vue+django实现下载文件
在实际项目,某些下载链接,是私密的。必须使用post方式,传递正确的参数,才能下载。
py3study
2021/03/04
2.1K0
vue+django实现下载文件
python测试开发django-112.文件下载功能
开发一个文件下载功能,在页面上点下载按钮,可以下载一个文件,如excel,word,pdf等
上海-悠悠
2021/09/14
3970
django:自定义静态文件服务器
静态文件使用nginx是比较有效率的,但是有时,我们需要对文件下载做细粒度的处理,比如鉴权下载,此时就需要写代码了。 下面将一步步实现一个自定义的文件handler。
超级大猪
2019/11/21
1.4K0
Python打包文件夹(zip/tar/
Code tells all: 一、zip import os, zipfile #打包目录为zip文件(未压缩) def make_zip(source_dir, output_filename):     zipf = zipfile.ZipFile(output_filename, 'w')         pre_len = len(os.path.dirname(source_dir))     for parent, dirnames, filenames in os.walk(source
py3study
2020/01/08
3K0
Python语言实现哈夫曼编码
汉语版:使用python实现huffman编码是一个能够很快地实现。所以我们选择使用python来实现我们这个程序。 l
py3study
2020/01/06
7200
测试开发进阶(三十六)
names中的 serializer使用 serializers.ProjectNameSerializer
zx钟
2019/11/14
3780
测试开发进阶(三十六)
python基础操作以及hdfs操作
一、前言        作为一个全栈工程师,必须要熟练掌握各种语言。。。HelloWorld。最近就被“逼着”走向了python开发之路,大体实现的功能是写一个通用类库将服务器本地存储的文件进行简单清洗后转储到HDFS中,所以基本上python的相关知识都涉及到了,这里对一些基础操作以及hdfs操作做一总结,以备查阅。 二、基础操作 2.1 字符串操作        字符串操作应该是所有语言的基础。python基本上也提供了其他语言常用的一些字符串处理函数,常用的如下: 1、startswith 以某个字
魏守峰
2018/04/28
1.1K0
django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV
这篇文档阐述了如何通过使用Django视图动态输出CSV (Comma Separated Values)。 你可以使用Python CSV 库或者Django的模板系统来达到目的。
ApacheCN_飞龙
2022/11/27
7570
Django2.0中文(非HTML)
1、返回非HTML:mimetype= from django.http import HttpResponse
用户5760343
2022/05/14
4450
5 分钟,带你快速入门 Django 文件上传下载
文件上传、下载作为基础功能,在 Web 项目中非常普遍,Django 项目如何实现文件上传下载?
AirPython
2021/04/20
1.1K0
5 分钟,带你快速入门 Django 文件上传下载
我的第八个项目:做一个web版停用词下载器
停用词是在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词,这些字或词即被称为Stop Words(停用词)
double
2022/01/26
4830
我的第八个项目:做一个web版停用词下载器
Django之文件上传下载
在文件上传期间,实际文件数据存储在request.FILES中。此字典中的每个条目都是UploadedFile对象(或子类) – 上传文件的简单包装器。UploadedFile对象是对Python file对象的一个简单封装,并带有Django特定的附加功能。需要表示文件的时候,Django内部会使用这个类。UploadedFile对象拥有下列属性和方法:
菲宇
2022/05/06
3.4K0
Django 文件下载
参考文章https://www.cnblogs.com/supery007/p/8146035.html
kirin
2020/05/21
1.1K0
django 实现文件下载功能
在实际的项目中很多时候需要用到下载功能,如导excel、pdf或者文件下载,当然你可以使用web服务自己搭建可以用于下载的资源服务器,如nginx,这里我们主要介绍django中的文件下载。
py3study
2020/02/18
4K0
django 实现文件下载功能
django之文件上传下载等相关
实现步骤: 1)创建项目Django_upload:django-admin startproject Django_upload;创建app:cd Django_upload;python manage.py startapp blog。 2)设计模型(M) 这里的模型只包括了两个属性:用户名(即谁上传了该文件);文件名。具体形式如下所示: #coding=utf-8 from __future__ import unicode_literals from django.db import models class NormalUser(models.Model): username=models.CharField('用户名',max_length=30) #用户名 headImg=models.FileField('文件',upload_to='./upload')#文件名 def __str__(self): return self.username class Meta: ordering=['username']#排序风格username 同步数据库:Python manage.py makemigrations python manage.py migrate 3)设计视图(V) view.py: #coding=utf-8 from django.shortcuts import render,render_to_response from django import forms from django.http import HttpResponse from blog.models import * # Create your views here. class NormalUserForm(forms.Form): #form的定义和model类的定义很像 username=forms.CharField() headImg=forms.FileField() #在View中使用已定义的Form方法 def registerNormalUser(request): #刚显示时调用GET方法 if request.method=="POST": uf = NormalUserForm(request.POST,request.FILES)#刚显示时,实例化表单(是否有数据) if uf.is_valid():#验证数据是否合法,当合法时可以使用cleaned_data属性。 #用来得到经过'clean'格式化的数据,会所提交过来的数据转化成合适的Python的类型。 username = uf.cleaned_data['username'] headImg = uf.cleaned_data['headImg'] #write in database normalUser=NormalUser()#实例化NormalUser对象 normalUser.username = username normalUser.headImg = headImg normalUser.save()#保存到数据库表中 return HttpResponse('Upload Succeed!')#重定向显示内容(跳转后内容) else: uf=NormalUserForm()#刚显示时,实例化空表单 return render(request,'register.html',{'uf':uf})#只有刚显示时才起作用 配置urls.py: from django.conf.urls import url from django.contrib import admin from blog.views import * urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^register/$',registerNormalUser), ] 4)设计模板与表单(T)templates/register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="
菲宇
2019/06/13
3.1K0
python ZipFile: output zip file,ByteIO
python 3.9zipFile出力结论:利用【zipfile】包import ioimport zipfile直接写入指定文件中:with zipfile.ZipFile(temp_path ,mode='w')as f: f.write(file)返回ByteIObuffer = io.BytesIO() # param1:写入对象 buffer # param2:mode write # param3:compression default'ZIP_STORED(no com
刀枪不入de王二花
2022/08/25
8900
python ZipFile: output  zip file,ByteIO
Django 实现文件上传下载API
by:授客 QQ:1033553122 欢迎加入全国软件测试交流QQ群:7156436
授客
2020/09/01
2.2K0
相关推荐
16.Django学习之文件上传和下载
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验