国产成人AV无码一二三区,少女1到100集,国产精品久久久久精品综合紧,巜公妇之诱感肉欲HD在线播放

文章 > Django > django如何从服务端下载文件到本地

django如何从服务端下载文件到本地

Django

头像

silencement

2019-08-19 09:12:556274浏览 · 0收藏 · 0评论

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

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

方式一:使用HttpResponse

import os
from django.http import HttpResponse, Http404
def 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 response
       except Exception:
           raise Http404

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

方式二:使用StreamingHttpResponse

import os
from django.http import HttpResponse, Http404, StreamingHttpResponse
def 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 response
   except Exception:
       raise Http404

方式三:使用FileResponse

import os
from django.http import HttpResponse, Http404, FileResponse
def 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 response
   except 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_path
from .models import Doc
import requests
import logging
logger = 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_url
            doc_url = settings.ITEM_DOMAIN_PORT + doc_url
            try:
                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 res
        else:
            raise Http404("文档不存在!")
关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

免费观看已满十八岁电视剧高清版 | 沉沦木之音| 三个老头拥着躁我一晚| 爸爸的擎天柱让我看第二集| 儿子娶妈妈免费观看完整版| 韩国男按摩师吸乳房会得乳腺癌吗 | 妈妈的朋友4| 《家访的老师》动浸在线观看| 芒果浏览器| 边吃奶边扭身体哼唧怎么回事 | 小洞流口水了 是不是饿了| 人犬兽人在线观看免费完整| 恋爱之瘾完整版在线全集免费观看| 女人吃男人鸡要多久恢复| 坤坤寒入桃子里电视剧免费看| 《麦子的秘密2》在线观看| 女性真人外生图片大全| 《炸裂吧!巨棒》免费阅读漫画| 按摩师把我添高潮了6次| XL上司| 看片| 《黏糊糊的你》免费观看| 欧美大片PPT免费PPT| B站暴躁少女CSGO| 三男一女CP免费观看电视剧大全| 成人香蕉 黄 色 网 站 视.. | 《黏糊糊的你》动漫免费观看| 俄罗斯少女2免费观看| 疯狂精力旺盛的女婿小说免费阅读| 苏软软汆肉的日常 花卷| 温柔女教师在线观看电视剧大全 | 宝宝今晚不带小雨伞| 《厨房激战5》完整版在线观看| 两个男人搞一个女人的心理| 成品人和精品人的特点分析| 年轻的嫂子| 共享女儿小诗1~10章的背景资...| EXO妈妈MV高清在线观看| Y8848影院电视剧免费| 母亲とが话しています读音| 公主很忙(N)笔趣阁免费阅读