flask 之上传与下载

from flask import Flask, render_template, request, send_from_directory, redirect, url_for
import os

app = Flask(__name__)

# 上传文件存储路径
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

@app.route('/')
def index():
    # 确保上传文件夹存在
    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])
    # 获取上传文件夹中的文件列表
    files = os.listdir(app.config['UPLOAD_FOLDER'])
    return render_template('up_down.html', files=files)

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return 'No file part'
	# 判断下是否有输入文件
    file = request.files['file']
    if file.filename == '':
        return 'No selected file'

    # 保存文件到指定路径
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
    # 更新网页,显示 index 页面
    return redirect(url_for('index'))

@app.route('/download/<filename>')
def download_file(filename):
    # 从上传文件夹中发送文件(下载)
    return send_from_directory(os.path.join(os.getcwd(), app.config['UPLOAD_FOLDER']), filename, as_attachment=True)

if __name__ == '__main__':
	# 以debug模式运行,只有当前电脑能访问此网页,其他电脑不行
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload and Download Example</title>
</head>
<body>

    <h2>File Upload</h2>
    
    <!-- 上传表单 -->
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" id="fileInput" accept=".txt, .pdf, .docx">
        <button type="submit">Upload</button>
    </form>

    <h2>File Download</h2>

    <!-- 下载文件列表 -->
    <ul>
        {% for file in files %}
            <li>
                <a href="{{ url_for('download_file', filename=file) }}" download="{{ file }}">{{ file }}</a>
            </li>
        {% endfor %}
    </ul>

</body>
</html>

这个上传下载的比较简陋,没有去美化他,这个无所谓,需要美化可以参考之前 登录界面 的文章,美化一下HTML界面,我这里就为了先试验下功能,没去美化
看下效果:
直接执行:
在这里插入图片描述
打开浏览器输入: 127.0.0.1:5000,得到网页:
在这里插入图片描述
我们点击 Choose File就能打开windows的弹窗去选择要上传的文件:
在这里插入图片描述
也许你会纳闷为啥什么都没有,注意看右下角,Open按钮上面,我们限定了文件格式,所以假如文件夹内没有,就不会显示
这个是在HTML中限制了,可以在下拉框中选择一下all files *.*就能识别其他格式的文件了
上面说的HTML中的设定就是这句 <input type="file" name="file" id="fileInput" accept=".txt, .pdf, .docx">
在这里插入图片描述
我在这里选择了 test.csv 档案,效果长这样:
在这里插入图片描述
我们点击Upload,就大功告成了:
在这里插入图片描述
因为我们在文件保存后重新返回了 index页面,所以马上刷新出来了我们刚刚上传的文件
,再看下我现在的文件夹格式:
在这里插入图片描述
uploads文件夹是脚本创建的,里面存放的是我们上传的文件
假设你没有添加任何文件直接点击Upload
页面会显示:
在这里插入图片描述
当然,这也是我们脚本的行为,你也可以写成如下这样,让它直接刷新网页,输入不为空才存储文件:

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return 'No file part'
	# 判断下是否有输入文件
    file = request.files['file']
    if file.filename != '':
    	# 保存文件到指定路径
    	file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
    # 更新网页,显示 index 页面
    return redirect(url_for('index'))

上传将过来,再来关注我们脚本的另一个功能,下载:
刚刚上面的截图可以看到,我们上传的文件 test.csv 是蓝色字体的,我们可以直接点击这档案进行下载
在这里插入图片描述
你也可以在这个test.csv 链接上点击鼠标右键,选择 save link as ,另存文件,就能选择存储地址了
在这里插入图片描述
下载主要靠命令:
return send_from_directory(os.path.join(os.getcwd(), app.config['UPLOAD_FOLDER']), filename, as_attachment=True)
文件路径:
os.path.join(os.getcwd(), app.config['UPLOAD_FOLDER'])
文件名:
filename
所以说我们能搞更多事情了
知道这个后,我们可以创建一个自己的上传下载网页,我们可以把网页上传的文件放到一个指定目录下,也允许别人通过网页获取到我们指定路径下的文件信息并下载。
经过这几天的学习,看起来想要做一个简单的网页其实非常简单,架构框架立起来,再慢慢的加一些功能,再慢慢美化加工,最后就能形成我们平时浏览的各种网页的样子。
当然,我现在接触的还是最最最基础的,但暂时够用…后续再试试完整做一套局域网的网页出来

简单初步的想法是:
把我的局域网网盘当做数据中心
做一个注册登录界面管理用户
做一个文件检索栏,快速查找文件
可以支持局域网内用户通过网页上传下载文件
对了,最好他能支持我生成目录,下载下来,比如说我想要知道我存了多少关于python 库的PDF档案等等,可以一键搜索关键字,并支持生成清单下载
这样做完应该能对flask等有更多些的了解,边做边学

嗯~~那这样是不是我也能通过网页做到一个网页播放视频音乐等等,私人网络家庭影院…(这个有点远,先一步一步来…)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/261700.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

理解按需自动导入 unplugin-auto-import unplugin-vue-components

文章目录 unplugin-auto-import基础使用构建工具引入插件配置插件 import&#xff1a;配置自动导入规则使用预设自动引入第三方库自动导入 TypeScript 类型vue 预设的自动导入配置 dts&#xff1a;让编辑器环境识别 ts 类型eslintrc&#xff1a;解决 eslint 检查错误dirs&#…

毕业单纯的钻研嵌入式知识有前景吗?

今日话题&#xff0c;毕业单纯的钻研嵌入式知识有前景吗&#xff1f;嵌入式领域的薪资相对一般&#xff0c;但有着巨大的上升空间。然而&#xff0c;嵌入式开发的学习路径可能相对曲折。其中&#xff0c;理解计算机结构是其中之一的挑战&#xff0c;因为嵌入式系统对稳定性要求…

MyBatis见解2

5.MyBatis的原始Dao开发-了解 使用Mybatis开发Dao&#xff0c;通常有两个方法&#xff0c;即原始Dao开发方式和Mapper接口代理开发方式。而现在主流的开发方式是接口代理开发方式&#xff0c;这种方式总体上更加简便。我们的课程讲解也主要以接口代理开发方式为主。在第4节已经…

一个很好用的Docker可视化管理工具

目录 前言Portainer安装部署使用 前言 一个好的docker可视化管理工具&#xff0c;可以提升我们不少的工作效率&#xff0c;下面我就推荐一个我使用过的&#xff0c;感觉很不错的一个可视化管理工具给大家 Portainer Portainer是一个开源的Docker管理工具&#xff0c;提供了容…

前端手动部署与自动化部署

连接服务器 先购买服务器 安装vscode插件 连接服务器 连接成功 手动部署 安装nginx 启动nginx systemctl start nginx systemctl status nginx systemctl enable nginx启动 检查状态 开机就启动nginx 开始手动部署 配置nginx 成功

数据库学习日常案例20231221-oracle libray cache lock分析

1 问题概述&#xff1a; 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。

【贪心】最优装载问题Python实现

文章目录 问题描述形式化描述 贪心算法贪心选择性质最优子结构性质 时间复杂性Python实现 个人主页&#xff1a;丷从心 系列专栏&#xff1a;贪心算法 问题描述 有一批集装箱要装上一艘载重量为 c c c的轮船&#xff0c;其中集装箱 i i i的重量为 w i w_{i} wi​在装载体积不受…

QT打包exe文件,在其它电脑里双击exe就可以直接运行

想要不依赖QT环境&#xff0c;在其它电脑里直接双击exe文件就可以运行当前程序。具体打包过程如下&#xff1a; 使用QT编译出release版本的exe release版本运行无误后&#xff0c;需要找到当前构建生成的exe所在文件夹 可以看到具体目录在这里 我在该目录下的bin文件夹里找到…

数据结构学习 Leetcode300最长递增子序列

是我在学习动态规划时遇到的一道题。 题目&#xff1a; 一共有两种解法&#xff1a; 动态规划贪心 二分&#xff08;很难理解&#xff0c;我还没完全懂。。。&#xff09; 解法一&#xff1a;动态规划 思路&#xff1a; 状态&#xff1a;nums的前i个数的最长递增子序列。dp…

ZKP Pasta Curves

Mina book[https://o1-labs.github.io/proof-systems/specs/pasta.html?highlightpasta#pasta-curves]学习笔记 Pasta Curves Pasta Curves is a fascinating innovation in cryptography designed by Zcash. What are the Pasta Curves The Pasta Curves are a pair of e…

Codeforces Round 916 (Div. 3)

Codeforces Round 916 (Div. 3) A. Problemsolving Log 题意&#xff1a;竞赛中有26个问题需要解决&#xff0c;每个问题名称为A到Z26个英文字母&#xff0c;按难度排序&#xff0c;做出A需要花费1分钟&#xff0c;B需要花费2分钟…以此类推。现在给出一个字符串表示竞赛日志…

【SpringBoot快速入门】(4)SpringBoot项目案例代码示例

目录 1 创建工程3 配置文件4 静态资源 之前我们已经学习的Spring、SpringMVC、Mabatis、Maven&#xff0c;详细讲解了Spring、SpringMVC、Mabatis整合SSM的方案和案例&#xff0c;上一节我们学习了SpringBoot的开发步骤、工程构建方法以及工程的快速启动&#xff0c;从这一节开…

js禁止打开控制台,如何强行打开控制台?

当我在查看某个网站的源码时&#xff0c;按F12会跳转到百度页面&#xff0c;或者先打开F12再输入网站也会进入到百度首页。 首先我们要关闭控制台进入到这个网站的首页&#xff0c;然后右键查 看网站的源码。 1.找到这个js文件&#xff0c;点进去。 2.点击这个js文件之后&a…

mysql:查看服务端没有睡眠的线程数量

使用命令show global status like Threads_running;可以查看服务端没有睡眠的线程数量。 例如&#xff1a;

Open3D 最小二乘拟合平面(直接求解法)

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫自重。 一、算法原理 平面方程的一般表达式为: A x + B y + C z

108基于matlab的使用模拟退火 (SA) 求解并行机器调度的程序

基于matlab的使用模拟退火 &#xff08;SA&#xff09; 求解并行机器调度的程序&#xff0c;程序已调通&#xff0c;可直接运行。 108 matlab模拟退火 &#xff08;SA) (xiaohongshu.com)

革命性突破:Great River推出XL高速ARINC 818传感器测试卡

Great River Technology荣幸地宣布&#xff0c;与RVS&#xff08;远程视觉系统&#xff09;2.0平台合作推出的XL高速ARINC 818传感器测试卡正式亮相。这款开创性的测试卡在柯林斯航空电子公司&#xff08;RTX业务部&#xff09;和波音公司开发和测试RVS 2.0系统中发挥了重要作用…

动态内存分配

为什么存在内存开辟 我们掌握的内存开辟方式有 int val 20;//在栈空间上开辟四个字节 char arr[10] {0}&#xff1b;//在栈空间上开辟十个连续的内存空间 但是上述开辟空间的方式有两个特点&#xff1a;1.空间开辟大小是固定的。 2.数组在申明的时候&#xff0c;必须指明数…

LCR 183. 望远镜中最高的海拔

解题思路&#xff1a; class Solution {public int[] maxAltitude(int[] heights, int limit) {if(heights.length 0 || limit 0) return new int[0];Deque<Integer> deque new LinkedList<>();int[] res new int[heights.length - limit 1];// 未形成窗口for…

程序员的50大JVM面试问题及答案

文章目录 1.JDK、JRE、JVM关系&#xff1f;2.启动程序如何查看加载了哪些类&#xff0c;以及加载顺序&#xff1f;3. class字节码文件10个主要组成部分?4.画一下jvm内存结构图&#xff1f;5.程序计数器6.Java虚拟机栈7.本地方法栈8.Java堆9.方法区10.运行时常量池&#xff1f;…