【Flask项目】文件分享系统(二)

前一篇文章简单分析了基于Flask的文件分享系统,功能设计的很简单,就是浏览目录,支持文件的上传和下载,那么用flask该如何来实现呢,其实也很简单。

一个Flask程序必须包含实例、路由、视图函数、响应,才能正常运行起来,本文也按这个顺序讲解,如果对Flask是什么不清楚的朋友请去看我写的前几篇关于flask的文章。

实例

生成实例的方式很简单,代码如下

python 复制代码
from flask import Flask
app = Flask(__name__, static_folder='./static', template_folder='./templates')

看过我写的《一个完整的Flask程序》一文的朋友可能会发现,这里的Flask实例中还添加了static_folder='./static', template_folder='./templates'参数,这两个参数是用来指定静态文件和模板文件路径的,指定后,flask会从这两个路径去寻找静态文件和html的模板。


读取目录内容

文件共享系统,首先要实现的就是读取目录内容,并区分出文件和文件夹并返回给浏览器,代码如下

python 复制代码
@app.route('/data/')
@app.route('/data/<path:subdir>/')
def index(subdir=''):
    if subdir == '':
        path = rootdir + 'data'
    else:
        path = rootdir + 'data' + os.sep + subdir

    # 判断如果是文件则下载
    if os.path.isfile(path):
        return(redirect(url_for('download', filepath=subdir)))

    # 显示文件、文件夹,计算文件大小
    dirlist = []
    filelist = []
    for i in os.listdir(path):
        if os.path.isdir(path + os.sep + i):
            dirlist.append(i + os.sep)
        else:
            filesize = os.path.getsize(path + os.sep + i)
            if (filesize / 1024) > 1000:
                filesize = str(round(float(filesize / 1024 /1024),2)) + 'MB'
            elif (filesize / 1024) < 1000:
                filesize = str(round(float(filesize / 1024),2)) + 'KB'
            filelist.append({"name":i, "size":filesize})
    return(render_template('index.html', currentpath=subdir, dirlist=dirlist, filelist=filelist))

以上代码中,将目录的浏览和文件的下载和在了一起,如果用户点击的是文件,就跳转到下载的视图函数,如果点击的是目录,则重新读取目录中的内容。

下面来详细解析下代码,前4行用于设置要读取的目录路径,然后判断浏览器传回的路由是否为文件,如果是文件则重定向到下载的视图函数,这里就要引入两个新的知识点,redirect()和url_for()函数,这两个函数是Flask中提供,使用from flask import redirect, url_for进行导入。

redirect函数用于重定向到另一个URL,它接收一个URL作为参数,然后返回一个重定向的响应对象,浏览器接到重定向的响应后,会重新发起新的URL的请求。这里的URL我们就需要用到url_for函数,这个函数可以让我们通过视图函数的名称和参数生成对应的URL地址。

接下来我们再看后面的代码,dirlist用于存储目录路径,filelist用于存储文件目录路径,后面的for循环用于读取目录下的所有文件和文件夹名称,如果是文件还要计算下文件的大小,然后将目录的路径存到dirlist中,将文件的路径存到filelist中,然后使用render_template渲染网页后返回给浏览器。这里要讲下render_template函数,也是flask提过的一个内部函数,render_template函数用于将HTML模板渲染成最终的HTML页面并返回给用户,其参数就是要渲染的html模板,和html中需要用到的变量,然后render_template函数使用变量在html模板中进行渲染,再返回给用户。使用from flask import render_template来导入这个函数。

到此,读取目录内容的视图函数就写好了。


下载文件

上面提到,如果传过来的是文件路径,则要重定向到文件下载的视图函数,其代码如下

python 复制代码
@app.route('/download/<path:filepath>/')
def download(filepath):
    fullpath = rootdir + 'data' + os.sep + filepath
    filename = fullpath.split(os.sep)[-1]
    dirpath = fullpath[:-len(filename)]
    return(send_from_directory(dirpath, filename, as_attachment=True))

从路由中获取到文件路径,然后组成文件是实际的绝对路径,使用send_from_directory函数将文件响应给浏览器,浏览器将会自动下载这个文件。send_from_directory函数也是flask的内置函数,使用from flask import send_from_directory来导入这个函数。send_from_directory函数接收文件路径和文件名,一定要带上as_attachment=True参数,告诉浏览器将文件下载到本地,而不打开文件。


这篇文章就先写到这里,下篇文章将文件上传和html模板,欢迎大家的关注!

相关推荐
小陈的进阶之路10 分钟前
爬虫三大解析库:lxml, jsonpath, bs4
开发语言·笔记·python
瑞码空间15 分钟前
Routing & API:前后端协作的本质与实现
前端·后端·接口·路由
SomeB1oody15 分钟前
【RustyML入门】2.10. 主成分分析
开发语言·后端·机器学习·rust·教程
我真是泰库辣18 分钟前
用TraeWork制作应用 —— 从 0 到 1 · 手把手搭建 opencode 网页对话网关
前端·后端
满怀冰雪23 分钟前
17-正则化方法:Dropout、权重衰减与过拟合控制
人工智能·python·深度学习·机器学习·paddlepaddle
2603_9651481125 分钟前
抖音/快手直播选品:用API快速匹配爆款与低价货源
开发语言·python·自动化·api
用户70887690393832 分钟前
RAG检索优化实战:从67%到92%,我做了这4步
python
亚雷33 分钟前
图解分布式架构:一个 Console,一群 Sidecar
后端·面试·程序员
GEOshijie12334 分钟前
智能家居品牌做GEO推荐哪家供应商?品类词抢占案例复盘
人工智能·python·智能家居
篮框坏了37 分钟前
配置改了不生效?我翻出 8 个坑,没一个报错
后端·spring cloud