在实际的项目中很多时候需要用到下载功能,如导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)写入用户本地磁盘,先不将它们载入服务器内存。

方式二:使用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

文件名中文乱码问题

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

response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(name))

文件私有化的两种方法

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

  • 上传文件放在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——三种方式实现文件下载相关推荐

  1. 使用apache-poi生成excel文件与同步请求三种方式与文件下载

    使用apache-poi生成excel文件 a)添加依赖: <!-- poi依赖--><dependency><groupId>org.apache.poi< ...

  2. Django中Model继承的三种方式

    Django中Model继承的三种方式 Django中Model的继承有三种: 1.抽象继承 2.多表继承 3.proxy model(代理model) 1.抽象继承 第一种抽象继承,创建一个通用父类 ...

  3. 三种方式让 Android WebView 支持文件下载

    三种方式让 Android WebView 支持文件下载 最近在开发的过程中遇到一个需求,那就是让 WebView 支持文件下载,比如说下载 apk.WebView 默认是不支持下载的,需要开发者自己 ...

  4. 前端实现文件下载功能的三种方式

    一些管理系统常常会有导出文件的功能,这里介绍三种文件下载的尝试 1. 通过文件地址下载文件 此方式最为简易,只需要知道文件在服务器上的地址,就可以通过a标签实现下载 <a href=" ...

  5. django文件上传到服务器,django上传文件的三种方式

    Django文件上传需要考虑的重要事项 文件或图片一般通过表单进行.用户在前端点击文件上传,然后以POST方式将数据和文件提交到服务器.服务器在接收到POST请求后需要将其存储在服务器上的某个地方.D ...

  6. STM32芯片烧录的三种方式介绍,串口、STM32 ST-LINK Utility以及STM32CubeProgrammer

    STM32芯片烧录的三种方式介绍,串口.STM32 ST-LINK Utility以及STM32CubeProgrammer 1 概述 1.1资源概述 1.2 STM32串口烧录方式 2.KEIL软件 ...

  7. 小程序引入icon的三种方式

    小程序引入icon的三种方式(原生图标.WeUI图标组件.iconfont图标) 原生图标 小程序里原生图标是通过icon标签来引入的: <icon type="success&quo ...

  8. Python实现微信支付(三种方式)

    Python实现微信支付(三种方式) 微信.支付宝二维码聚合SDK下载 点我下载 关注公众号"轻松学编程"了解更多. 如果需要python SDk源码,可以加我微信[1257309 ...

  9. response设置编码的三种方式以及比较

    https://blog.csdn.net/u010653908/article/details/53994021 response设置编码的三种方式以及比较 2017年01月03日 14:12:46 ...

  10. go引入外部依赖的三种方式:go get,go module,vendor目录

    本文转载自golang 引入外部包的三种方式:go get, go module, vendor目录_guoguolifang的博客-CSDN博客_golang 外部包 import  "g ...

最新文章

  1. 文档计算机无法分页,同一EXCEL文件在不同计算机上显示分页不同解决办法(6页)-原创力文档...
  2. Spring boot的@Value注解
  3. SonarQube4.4+Jenkins进行代码检查实例之三-单元测试分析
  4. 如何轻松拿到大厂面试offer | 掘金技术征文
  5. .NET Core 2.1.5和.NET Core SDK 2.1.403发布
  6. 软考信息安全工程师备考笔记5:第五章应用系统安全基础备考要点
  7. tomcat通过一个端口号实现多域名访问
  8. c语言输入n打印数字菱形,打印数字菱形,急啊,帮帮小女子啊。。。
  9. 001 java_001Java开发环境
  10. 自学PL/SQL 第一讲decalring variables
  11. 带你搭建一个H5游戏平台,附源码下载
  12. 华为身处“创新者的窘境”,而浑然不觉(转载)
  13. SQL注入-waf绕过
  14. 再安利几个看片追剧的App
  15. arcgis 线段合并
  16. C/C++ 时间知识总结
  17. linux-web服务
  18. libco源码解析(2) 创建协程,co_create
  19. 如何在XP HOME版下设置共享文件夹及其权限?
  20. idea必备配置和插件

热门文章

  1. ILRuntime入门11 LitJson
  2. CBoard项目学习
  3. liteon460w服务器电源管理系统,PS-5251-06 LITEON光宝工业电源
  4. 最新MT2503_GPS调试工具资料下载
  5. oracle库sql根据拼音查汉字,根据拼音首字母模糊查询数据库中文字段
  6. ASCII码对照表 包含二进制、十进制、十六进制
  7. .NET程序员面试题总结
  8. JAVASCRIPT加密解密终级指南
  9. 能制作引导系统型U盘的几个软件工具
  10. matlab vgg19提取语义特征,keras中VGG19预训练模型的使用