flask 接口上传文件

您所在的位置:网站首页 flask文件目录 flask 接口上传文件

flask 接口上传文件

2023-02-21 08:45| 来源: 网络整理| 查看: 265

图 | 源网络 文 | 5号程序员 01

事情是这样的。

有一天五号程序员打算网购一盒巧克力送给自己的女朋友

想必女朋友收到礼物是这样的:

结果商家邮寄来的巧克力中夹着一张纸条:

害!你说气不气人,现在都还没理我!

这不投诉更待何时?

打开投诉界面一看,咦?要求上传图片。

哈~既然说起上传,那咱们就先说一下如何使用Flask上传文件。

02

使用Flask上传文件的简单实现

Flask文件上传比较简单,主要是下面3点:

一个标签被标记有enctype= multipart/form-data ,并且在里面包含一个标签

服务端应用通过请求对象上的files字典访问文件

使用文件的save()方法将文件永久的保存在文件系统的某处

既然涉及到保存,那肯定会用到路径。下面是os.path方法的相关属性:

os.path.sep:Windows下路径分隔符,即反斜杠‘\’

os.path.altsep:Linux下路径分隔符,即斜杠‘/‘

当前目录:os.path.curdir

父目录:os.path.pardir

绝对路径:os.path.abspath(path)

有了这些基本知识就够了,接下来直接实战。新建app.py文件,内容如下:

from flask import Flask,render_template,requestfrom os import pathfrom werkzeug.utils import secure_filenameapp = Flask(__name__)@app.route('/', methods=['GET', 'POST'])def index(): if requesthod == 'GET': return render_template('upload.html') else: f = request.files['file'] filename = secure_filename(f.filename) f.save(path.join('D:/test', filename)) #文件的具体路径根据个人而定,这里以D盘test文件夹为例 return "上传文件成功!"if __name__ == "__main__": app.run(debug=True)

导入secure_filename方法是为了在传入中文文件名时过滤掉中文名,只留下文件名后缀;path.join()则可以整合路径。

在templates文件夹下新建upload.html文件,用于文件上传:

文件上传title>.div1 { height:180px; width:380px; border:1px solid #8A8989; margin:0 auto;}.input { display: block; width:250px; height:30px; margin:10px auto;}.button { background: #2066C5; color:white; font-size:18px; font-weight: bold; height: 30px; border-radius: 4px;}style>head> form>div>body>html>

运行文件后将能看见如下界面:

选择指定的word文件:

点击上传,显示“上传成功”:

由于在form标签中action属性没有指定其他网页,所以会跳转到同一个网址,但此时的requesthod已经由GET变为POST,所以执行else下的代码。

看一下文件夹内有没有:

成功!我们的电脑就像一个服务器,可以实现任意文件的上传,但是以中文命名的文件上传时会出现中文丢失。

03 改进上传功能

虽然上面的代码实现了文件上传功能,但还有一些不足:

文件没有重新命名,多名用户上传同名文件如何处理?

没有实现文件目录自动创建,文件保存失败怎么办?

文件上传时没有进行文件格式检验,影响数据安全怎么设卡?

为了解决上述问题,新建form.py文件用于表单验证:

from wtforms import Form,FileFieldfrom flask_wtf.file import FileRequired,FileAllowedclass UploadForm(Form): file = FileField(validators=[FileRequired(), FileAllowed(['jpg','png','gif'])])

其中,FileRequired()用来验证文件上传是否为空,FileAllowed()用来验证上传文件的后缀名。

然后修改app.py文件:

from flask import Flask,render_template,request,send_from_directoryimport timeimport osfrom os import pathfrom werkzeug.utils import secure_filenamefrom werkzeug.datastructures import CombinedMultiDictimport platformfrom form import UploadFormapp = Flask(__name__)#判断系统,使用不同分隔符if platform.system() == "Windows": slash = '\\'else: platform.system() == "Linux" slash = '/'UPLOAD_PATH = 'D:' + slash + 'uploads' + [email protected]('/', methods=['GET', 'POST'])def index(): if requesthod == 'GET': return render_template('upload.html') else: if not path.exists(UPLOAD_PATH): os.makedirs(UPLOAD_PATH) #路径不存在时创建路径 form = UploadForm(CombinedMultiDict([request.form, request.files])) if form.validate(): f = request.files['file'] filename = secure_filename(f.filename) ext = filename.rsplit('.', 1)[1] #获取文件后缀 unix_time = int(time.time()) #获取时间用于命名,不会重复 new_filename = str(unix_time) + '.' + ext f.save(path.join(UPLOAD_PATH, new_filename)) return "上传文件成功!" else: "仅支持jpg、png和gif格式的文件!" @app.route('/images//', methods=['GET', 'POST'])def get_image(filename): return send_from_directory(UPLOAD_PATH, filename)if __name__ == "__main__": app.run(debug=True)

其中,os.makedirs()可以自动创建文件路径,然后用CombinedMultiDict() 把form和file的数据结合起来一起验证,用时间戳加文件后缀重新命名文件,最后新建get_image()视图函数用于下载文件,send_from_directory(dirpath, filename)函数可以实现文件在线下载功能。

运行app.py,选择在桌面上的“handsome.jpg”文件:

点击上传可以看到“文件上传成功!”。找一下电脑中的源文件:

可以看到在D盘下生成了uploads文件夹,接下来在浏览器访问:http://127.0.0.1:5000/images/xxx.jpg/,根据保存时的文件名输入网址实现在线下载功能。

如果上传word文档行不行呢?试一下:

不行!报错!

因为上传的文件只能是三种图片格式!

04

看到这里有些小伙伴可能会感到熟悉,是不是在哪里见过?

没错,百度贴吧!

登录百度美图吧,随机找到一张图片并打开:

观察其网址,再点开同一帖子下的图片观察其网址,你会发现其中的命名规则。

今天的内容图比较多,看起来比较费劲,上传文件的内容非常重要,需要小伙伴们多加练习才能掌握!

下一次,我们将谈一谈经常提到的Cookies。

你确定不关注我一波?!

- END -



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3