文件上传的相关详细步骤:

1、文件上传的小例子

1、新建images文件夹用来存放上传的图片
2、templates文件夹中创建模板文件upload.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>upload</title>
  6. </head>
  7. <body>
  8. <!-- enctype="multipart/form-data"加上不要忘 -->
  9. <form action="" method="post" enctype="multipart/form-data">
  10. <table>
  11. <tr>
  12. <td>头像</td>
  13. <td><input type="file" name="image_file"></td>
  14. </tr>
  15. <tr>
  16. <td>描述</td>
  17. <td><input type="text" name="desc"></td>
  18. </tr>
  19. <tr>
  20. <td><input type="submit" value="上传"></td>
  21. </tr>
  22. </table>
  23. </form>
  24. </body>
  25. </html>

注意点:
再上传文件时,需要在form中写入enctype=”multipart/form-data”这一参数
网页展示:
image.png
主文件入口:

  1. from flask import Flask, request, render_template
  2. # 用来拼接文件路径
  3. import os
  4. app = Flask(__name__)
  5. @app.route("/")
  6. def home():
  7. return "首页"
  8. @app.route("/upload/", methods=["GET", "POST"])
  9. def upload():
  10. if request.method == "GET":
  11. return render_template("upload.html")
  12. else:
  13. # 接受文字或者数字时使用的request.form.get()进行接受
  14. desc = request.form.get("desc")
  15. # 对于文件则需要使用request.files.get()进行接收
  16. image_file = request.files.get("image_file")
  17. # image_file.save()中传入的是images//文件名这种格式,所以需要os进行拼接
  18. image_file.save(os.path.join("images", image_file.filename))
  19. return "文件上传成功"
  20. if __name__ == '__main__':
  21. app.run(debug=True)

2、werkzeug.utils.secure_filename对文件名进行过滤

  1. from flask import Flask, request, render_template
  2. import os
  3. # 通过该方法可以将文件中的一些空格、点进行处理
  4. from werkzeug.utils import secure_filename
  5. app = Flask(__name__)
  6. @app.route("/")
  7. def home():
  8. return "首页"
  9. @app.route("/upload/", methods=["GET", "POST"])
  10. def upload():
  11. if request.method == "GET":
  12. return render_template("upload.html")
  13. else:
  14. desc = request.form.get("desc")
  15. image_file = request.files.get("image_file")
  16. filename = secure_filename(image_file.filename)
  17. image_file.save(os.path.join("images", filename))
  18. return "文件上传成功"
  19. if __name__ == '__main__':
  20. app.run(debug=True)

注意点:filename = secure_filename(image_file.filename)由于采取的是ascii的编码方式,所以会将中文进行删除,如下:
image.png
image.png
解决方法,在如下链接:
https://blog.csdn.net/qq_36390239/article/details/98847888
文件重名的问题(重命名),uuid了解一些

3、对上传文件进行表单验证

为了规范上传的文件格式以及方式一些病毒的注入,因此需要对上传的文件进行表单验证
新建forms.py文件

  1. from wtforms import Form, FileField, StringField
  2. from wtforms.validators import InputRequired
  3. # FileRequired文件必须上传, FileAllowed可以传入的种类
  4. from flask_wtf.file import FileAllowed, FileRequired
  5. class UploadForm(Form):
  6. image_file = FileField(validators=[FileRequired(), FileAllowed(["jpg", "png", "gif"])])
  7. desc = StringField(validators=[InputRequired()])

此时表单中上传了文件,form = UploadForm(request.form)已经不能满足要求需要额外导入
from werkzeug.datastructures import CombinedMultiDict

  1. from flask import Flask, request, render_template
  2. import os
  3. from werkzeug.utils import secure_filename
  4. # 将request.form和request.files一起传入UploadForm()中
  5. from werkzeug.datastructures import CombinedMultiDict
  6. from forms import UploadForm
  7. app = Flask(__name__)
  8. @app.route("/")
  9. def home():
  10. return "首页"
  11. @app.route("/upload/", methods=["GET", "POST"])
  12. def upload():
  13. if request.method == "GET":
  14. return render_template("upload.html")
  15. else:
  16. # 注意直接传入变量CombinedMultiDict([request.form, request.files]
  17. form = UploadForm(CombinedMultiDict([request.form, request.files]))
  18. if form.validate():
  19. # 由于定义了form,所以下面的代码可以进行改写
  20. # desc = request.form.get("desc")
  21. desc = form.desc.data
  22. # image_file = request.files.get("image_file")
  23. image_file = form.image_file.data
  24. filename = secure_filename(image_file.filename)
  25. image_file.save(os.path.join("images", filename))
  26. return "文件上传成功"
  27. else:
  28. print(form.errors)
  29. return "文件上传失败"
  30. if __name__ == '__main__':
  31. app.run(debug=True)

4、通过路由访问资源

  1. # 导入send_from_directory方法
  2. from flask import send_from_directory
  3. ...
  4. # 定义一个访问的方法,filename是想要的访问的文件名
  5. @app.route("/images/<filename>")
  6. def images(filename):
  7. return send_from_directory('images', filename)