上传文件
用 Flask 处理文件上传很简单。只要确保你没忘记在 HTML 表单中设置 enctype="multipart/form-data" 属性,不然你的浏览器根本不会发送文件。
已上传的文件存储在内存或是文件系统中一个临时的位置。你可以通过请求对象的 files 属性访问它们。每个上传的文件都会存储在这个字典里。它表现近乎为一个标准的 Python file 对象,但它还有一个 save() 方法,这个方法允许你把文件保存到服务器的文件系统上。
我们以上传图片为例:假设将上传的图片只允许'png'、'jpg'、'jpeg'、'gif' 这四种格式,通过url/upload使用POST上传,上传的图片存放在服务器端的static/uploads目录下。
首先在项目HelloWorld中创建目录static/uploads, 这时候我们的目录结构为:
HelloWorld/
├ static/
│ ├ uploads/
├ templates/
├ server.py
├ client.py
werkzeug库可以判断文件名是否安全
我们安装这个库
pip install werkzeug
server.py代码:
from flask import Flask, request
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
# 文件上传目录
app.config['UPLOAD_FOLDER'] = 'static/uploads/'
# 支持的文件格式
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'} # 集合类型
# 判断文件名是否是我们支持的格式
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
@app.route('/upload', methods=['POST'])
def upload():
upload_file = request.files['image']
if upload_file and allowed_file(upload_file.filename): # 上传前文件在客户端的文件名
filename = secure_filename(upload_file.filename)
# 将文件保存到 static/uploads 目录,文件名同上传时使用的文件名
upload_file.save(os.path.join(app.root_path, app.config['UPLOAD_FOLDER'], filename))
return 'info is '+request.form.get('info', '')+'. success'
else:
return 'failed'
if __name__ == '__main__':
app.run(port=5000, debug=True)
app.config中的config是字典的子类,可以用来设置自有的配置信息,也可以设置自己的配置信息。
函数allowed_file(filename)用来判断filename是否有后缀以及后缀是否在app.config['ALLOWED_EXTENSIONS']中。
upload_file是上传文件对应的对象。
app.root_path获取server.py所在目录在文件系统中的绝对路径。
upload_file.save(path)用来将upload_file保存在服务器的文件系统中,参数最好是绝对路径。函数os.path.join()用来将使用合适的路径分隔符将路径组合起来。
客户端client.py:
import requests
file_data = {'image': open('flask.jpg', 'rb')}
user_info = {'info': 'flask'}
r = requests.post("http://127.0.0.1:5000/upload", data=user_info, files=file_data)
print(r.text)
运行:
11我们看到图片已经上传成功了
要控制上产文件的大小,可以设置请求实体的大小,例如:
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
不过,在处理上传文件时候,需要使用try:...except:...。
如果要获取上传文件的内容可以:
file_content = request.files['image'].stream.read()
网友评论