首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >django 实现文件下载功能

django 实现文件下载功能

作者头像
py3study
发布2020-02-18 21:44:56
3.8K0
发布2020-02-18 21:44:56
举报
文章被收录于专栏:python3python3

一、概述

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

前端实现方式

a标签+响应头信息

<a href="/download/1/">下载图片</a>

注意:这里的1指的是MySQL表的主键id

后端实现方式

使用django有三种文件下载方式,分别是HttpResponse,StreamingHttpResponse,FileResponse

详情,请参考链接

https://www.jb51.net/article/137790.htm

本文主要介绍StreamingHttpResponse实现方式

二、实际操作

新建项目

新建一个Django项目untitled1,这里的是Django 2.x版本。

目录结构如下:

./
├── app
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── manage.py
├── templates
│   └── index.html
├── untitled1
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── upload
    └── images
        └── animation.jpg

默认创建了一个应用,名叫app

upload是用来存放上传的图片

简单示例

这里以一个简单的页面,来介绍如何实现下载功能!

修改urls.py,增加路由。

注意:红色部分,是需要修改的

from django.contrib import admin
from django.urls import path,re_path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
    re_path('download/(?P<id>\d+)', views.file_down,name = "download"),
]

修改views.py,增加视图函数

from django.shortcuts import render, HttpResponse
from django.http import StreamingHttpResponse
import os

def index(request):
    return render(request,"index.html")

# Create your views here.
def file_down(request, id):
    """
    下载压缩文件
    :param request:
    :param id: 数据库id
    :return:
    """
    data = [{"id":"1","image":"animation.jpg"}]  # 模拟mysql表数据
    file_name = ""  # 文件名
    for i in data:
        if i["id"] == id:  # 判断id一致时
            file_name = i["image"]  # 覆盖变量
    
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 项目根目录
    file_path = os.path.join(base_dir, 'upload','images', file_name)  # 下载文件的绝对路径

    if not os.path.isfile(file_path):  # 判断下载文件是否存在
        return HttpResponse("Sorry but Not Found the File")

    def file_iterator(file_path, chunk_size=512):
        """
        文件生成器,防止文件过大,导致内存溢出
        :param file_path: 文件绝对路径
        :param chunk_size: 块大小
        :return: 生成器
        """
        with open(file_path, mode='rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break

    try:
        # 设置响应头
        # StreamingHttpResponse将文件内容进行流式传输,数据量大可以用这个方法
        response = StreamingHttpResponse(file_iterator(file_path))
        # 以流的形式下载文件,这样可以实现任意格式的文件下载
        response['Content-Type'] = 'application/octet-stream'
        # Content-Disposition就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(file_name)
    except:
        return HttpResponse("Sorry but Not Found the File")

    return response

代码解释:

index是默认的首页展示

file_down 是用来做下载的。

为了简单实现,在file_down 中的data,表示数据库中的记录。需要指定id才能对应的文件!

其他代码,有详细的注释,这里就不多介绍了

修改index.html,注意:这里需要指定id。这里仅做示例,固定了id。

实际情况应该查询数据库,使用Django模板引擎来渲染的

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="/download/1/">下载图片</a>
</body>
</html>

upload目录是用来存放上传文件的。在images里面我放了一张动漫图片!

启动项目,访问首页:

这里使用的是edge浏览器

1.png
1.png

点击下载图片,浏览器底部会有提示

点击打开

就会打开图片,效果如下:

3.png
3.png
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概述
    • 前端实现方式
      • a标签+响应头信息
    • 后端实现方式
      • 二、实际操作
        • 新建项目
          • 简单示例
          相关产品与服务
          云数据库 MySQL
          腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档