目录

方式一:使用HttpResponse

方式二:使用StreamingHttpResponse

方式三:使用FileResponse

方式四:使用迭代器优化文件加载

文件名中文乱码问题

文件私有化的两种方法

个人下载文档view视图代码


在实际的项目中很多时候需要用到下载功能,如导excel、pdf或者文件下载,当然你可以使用web服务自己搭建可以用于下载的资源服务器,如nginx,这里我们主要介绍django中的文件下载。

这里我们将下载的文件存放在项目media目录下,当然在实际中并不会这样做。

方式一:使用HttpResponse

import os
from django.http import HttpResponse, Http404def media_file_download(request, file_path):with open(file_path, 'rb') as f:try:response = HttpResponse(f)response['content_type'] = "application/octet-stream"response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)return responseexcept Exception:raise Http404

HttpResponse有个很大的弊端,其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法,这两个方法将下载文件分批(Chunks)写入用户本地磁盘,先不将它们载入服务器内存。如果一定要使用HttpResponse,可以参考方式四。

方式二:使用StreamingHttpResponse

import os
from django.http import HttpResponse, Http404, StreamingHttpResponsedef stream_http_download(request, file_path):try:response = StreamingHttpResponse(open(file_path, 'rb'))response['content_type'] = "application/octet-stream"response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)return responseexcept Exception:raise Http404

方式三:使用FileResponse

import os
from django.http import HttpResponse, Http404, FileResponsedef file_response_download1(request, file_path):try:response = FileResponse(open(file_path, 'rb'))response['content_type'] = "application/octet-stream"response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)return responseexcept Exception:raise Http404

方式四:使用迭代器优化文件加载

import os
from django.http import HttpResponse, Http404# 这是一个迭代器,减少内存占用
def read_file(url, chunk_size=512):with open(url, "rb") as f:while True:c = f.read(chunk_size)if c:yield celse:breakdef stream_http_download(request, file_path):try:response = HttpResponse(read_file(file_path))response['content_type'] = "application/octet-stream"response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)return responseexcept Exception:raise Http404

文件名中文乱码问题

其中用英文的文件名,浏览器显示正常,但是用了中文后,就是默认的文件名,如下载.xls,或者如果我用了utf-8编码,是乱码。解决方法如下:

response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(name))
response['Content-Disposition'] = 'attachment;filename="{0}{1}{2}{3}"'.format(datetime.now().year,datetime.now().month,datetime.now().day,'三率.xls').encode('utf-8', 'ISO-8859-1')

文件私有化的两种方法

如果你想实现只有登录过的用户才能查看和下载某些文件,大概有两种方法,这里仅提供思路。

  • 上传文件放在media文件夹,文件名使用很长的随机字符串命名(uuid), 让用户无法根据文件名猜出这是什么文件。视图和模板里验证用户是否已登录,登录或通过权限验证后才显示具体的url。- 简单易实现,安全性不高,但对于一般项目已足够。
  • 上传文件放在非media文件夹,用户即使知道了具体文件地址也无法访问,因为Django只会给media文件夹里每个文件创建独立url资源。视图和模板里验证用户是否已登录,登录或通过权限验证后通过自己编写的下载方法下载文件。- 安全性高,但实现相对复杂。

个人下载文档view视图代码

from django.views import View
from django.conf import settings
from django.http import FileResponse,Http404
from django.utils.encoding import escape_uri_pathfrom .models import Docimport requests
import logginglogger = logging.getLogger('django')
class Download(View):"""前端传来下载doc的id,后端传给它下载地址"""def get(self,request,doc_id):doc = Doc.objects.only('file_url').filter(is_delete=False,id = doc_id).first()if doc:doc_url = doc.file_urldoc_url = settings.ITEM_DOMAIN_PORT + doc_urltry:res = FileResponse(requests.get(doc_url,stream = True))except Exception as e:logger.info('文件获取异常:{}'.format(e))raise Http404('文件获取异常')file_end = doc_url.split('.')[-1]if not file_end:raise Http404('文档路径出错')else:file_end = file_end.lower()if file_end == "pdf":res["Content-type"] = "application/pdf"elif file_end == "zip":res["Content-type"] = "application/zip"elif file_end == "doc":res["Content-type"] = "application/msword"elif file_end == "xls":res["Content-type"] = "application/vnd.ms-excel"elif file_end == "docx":res["Content-type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"elif file_end == "ppt":res["Content-type"] = "application/vnd.ms-powerpoint"elif file_end == "pptx":res["Content-type"] = "application/vnd.openxmlformats-officedocument.presentationml.presentation"else:raise Http404("文档格式不正确!")doc_filename = escape_uri_path(doc_url.split('/')[-1])# http1.1 中的规范# 设置为inline,会直接打开# attachment 浏览器会开始下载res["Content-Disposition"] = "attachment; filename*=UTF-8''{}".format(doc_filename)return reselse:raise Http404("文档不存在!")

参考链接:

django——三种方式实现文件下载

Django下载文件——三种方法和大文件下载相关推荐

  1. Go-读取文件和写入文件三种方法的操作

    打开和关闭文件操作: os.Open()函数能够打开一个文件,返回一个*File和一个err.对得到的文件实例调用close()方法能够关闭文件. package main import (" ...

  2. python 实现账号封禁30分钟---(Redis,Mysql,文件)三种方法

    下面写三种方法来实现,用户在规定时间内,输入次数上限,封禁账号的功能. 第一种:使用redis完成用户封禁状态 第二种:使用mysql 第三种:使用文件 1.封禁用户流程图  第一种方法: Redis ...

  3. python3.4.4实现网页爬虫基础之网页下载器三种方法

    这是是慕课网<Python开发简单爬虫>中网页下载器的三种实现方法,课程用的是python2.7,这里用最新的3.4.4实现出来,分享给新人: import urllib.request ...

  4. github下载加速三种方法

    第一种方法: 在github.com后面加  .cnpmjs.org 例如我现在要用git下载gorm项目  https://github.com/go-gorm/gorm 想要加速则使用指令  gi ...

  5. c#.Net MVC服务端下载文件、限制下载速度、大文件下载、对性能的影响、对大文件的支持、对断点续传和多线程下载的支持

    一.ASP.NET文件下载各种方式比较:对性能的影响.对大文件的支持.对断点续传和多线程下载的支持 asp.net里提供了多种方式,从服务器端向客户端写文件流,实现客户端下载文件.这种技术在做防下载系 ...

  6. VMWare虚拟机和主机共享/传输/拷贝文件三种方法

    首先要安装虚拟机工具VMWare Tool这样鼠标进出使用也方便. 1.虚拟机和主机之间在安装了VMWare Tool之后可以实现剪贴板的共享,即可以复制粘贴.但是中文目录和中文文件和带空格的路径会出 ...

  7. 【Django下载文件-Kml文件下载】

    Django下载文件系列 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 第一章 开发应该了解的Web文件下载 第二章 Django下载文件-三种方法 第三章 Django下载文件- ...

  8. JS下载文件的三种方法

    因为公司后端忙得无法给批量下载的api,就我们前端自己把多张图片打包成zip下载,zip打包我们用的是jszip,下面是js实现下载的三种方法: 利用HTML download 属性 var a = ...

  9. Powershell下载文件的三种方法

    Powershell下载文件的三种方法 Invork-WebRequest WebClient对象 BitsTransfer模块 layout: post title: Powershell下载文件的 ...

  10. python 网站文件下载-python实现下载文件的三种方法

    Python开发中时长遇到要下载文件的情况,最常用的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib从ftp站点下载文件.此外Python还提供了另外一种方法 ...

最新文章

  1. javascript对时间的处理
  2. 数据结构与算法——并查集(不相交集合)
  3. Win11系统如何调节字体大小
  4. react native text换行_基于React+Koa实现React SSR服务端渲染
  5. 电信用户遭重!iPhone 13全系列不再支持中国电信2G/3G网络
  6. 韩流音乐爱好者的福音!SM娱乐牵手腾讯音乐
  7. 20145209 2016-2017-2 《Java程序设计》第5周学习总结
  8. HTML 中img标签不显示
  9. 问题以及发现问题和解决问题
  10. SQL 实战教程(八)
  11. nc 模拟服务器_Linux网络利器netcat/nc
  12. 回归远程 - 云原生IDE是IaC从表象触达本质的必然选择 | SmartIDE
  13. 利用Arcgis制作数据统计图
  14. 制作字幕.html教程,手机拍的视频如何加字幕 字幕制作软件使用教程
  15. Unity 场景光照出现问题
  16. R语言使用gbm包的gbm函数拟合梯度提升机回归模型:使用predict函数和训练好的模型进行预测推理、计算回归模型的评估指标MAE、MSE、RMSE、R方等指标
  17. 信息系统项目管理师核心考点(六十四)信息安全基础知识重要概念
  18. 学术英语写作(更新中)
  19. 解决rdlc报错 An error occurred during local report processing
  20. 2022跨年烟花代码、用Python送你一场跨年烟花秀

热门文章

  1. zend studio 调试php,在Zend Studio中调试PHP(5/5)
  2. mysql手册06_触发器
  3. oppo r11s鸿蒙固件,OPPO R11s刷机包
  4. linux救黑砖手机,手机黑砖9006/9008救砖教程 通用救砖模式详细流程
  5. 下载elasticsearch的jdbc包
  6. k8s启动Pod报错CrashLoopBackOff
  7. 手机浏览器哪个好用,UC、多御和QQ浏览器对比
  8. U盘安装WIN10移动系统
  9. 免费下载Microsoft Visual C++ 2010 Express (VSExpress)安装包地址分享速进
  10. 微信H5 跳转小程序 (html版本)