Flask上传文件

上传文件包括很多,比如用户头像,文章图片,文件分享等等,它也涉及到很多内容:上传文件,过滤文件类型,限制大小,文件名的编辑,拖拽上传,进度条,文件命名,文件目录的管理等等.

文件上传的基本概念非常简单:

  1. 一个在HTML 文档中定义的好的form标签(),并且form中必须包含一个标签
  2. 服务端应用通过请求对象上的request.files字典访问文件.
  3. 使用文件对象的save()方法将文件永久的保存在文件系统中.

示例代码

https://github.com/ningwenyan/demo_code/tree/master/flask_demo_code/T14

1.flask 原生文件上传

目录结构

file_upload_1 ├── app.py              #    主程序├── config.py           # 配置文件├── static                  # css,js文件├── templates         # 渲染模板文件│   └── uploads.html               # 上传html文件└── uploads               # 上传文件的文件夹

uploads.html实现一个简单的上传功能,需要注意的是,必须写enctype="multipart/form-data

html><html lang="en"><head>    <meta charset="UTF-8">    <title>上传title>head><body>    <form action="" method="post" enctype="multipart/form-data">        <table>            <tr>                <td>上传文件td>                <td><input type="file" name="file">td>            tr>            <tr>                <td><label for="#"><input type="submit">label>td>            tr>        table>

    form>body>html>

config.py

import os

DEBUG=TrueTEMPLATES_AUTO_RELOAD=Truepar_dir = os.path.dirname(__file__)       UPLOAD_FOLDER=par_dir+'/uploads/'                   # 指定要上传的文件夹MAX_CONTENT_LENGTH=16*1024*1024                 # 指定上传的文件的最大大小

app.py

from flask import Flaskimport configfrom flask import request,render_template,send_from_directoryfrom werkzeug.utils import secure_filenameimport os

app = Flask(__name__)app.config.from_object(config)

@app.route('/')def hello_world():     return 'Hello World!'

ALLOWED_EXTENSIONS = set(['txt','pdf','png','jpg','jpeg','gif'])

# 判断文件后缀def allowed_file(filename):     return '.' in filename and filename.rsplit('.',1)[1] in ALLOWED_EXTENSIONS

# 定义上传文件路由@app.route('/uploads/',methods=['GET','POST'])def upload_file():       if request.method == 'GET':           return  render_template('uploads.html')     else:        # 文件类型不能用 request.form.get() 获取        # 要使用 request.files.get() 方法        file = request.files.get('file')        # 可以通过 文件对象的 filename 属性拿到文件名        if file and allowed_file(file.filename):            # 出于安全考虑,使用 security filename            filename = secure_filename(file.filename)            print(app.config['UPLOAD_FOLDER'])            file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))          return render_template('uploads.html')

# 定义访问上传文件路径@app.route('/uploads/')def uploads_file(filename):     # 调用 send_from_directory 方法提供对已上传文件的访问服务     return send_from_directory(app.config['UPLOAD_FOLDER'],filename)

if __name__ == '__main__':    app.run()

需要注意的是:

  • 必须手动验证上传的文件后缀,不符合的不上传
  • 使用request.file.get() 方法获取文件,而不是request.form.get(),虽然文件处于表单中,但是文件定义在另外的方法中
  • file.save() 方法来指定保存文件的最终路径
  • 使用security_filename 来处理文件名,不能相信用户上传的任何东西
  • 可以定义回显来上传的文件,这个需要send_from_directory 方法的支持.

2.Flask-Uploads

Flask-Uploads 简化加强了flask 的原生上传功能.

Flask-Uploads 中有一个UploadSet 的概念,用他来统一验证要上传的文件类型,以及文件名称的安全问题.

1.安装

$ pip install flask-upload

2.基本概念

  1. 文件类型过滤

设置文件上传的路径和文件类型:(在config.py文件中指定)

  • UPLOADED_FILES_DEST: 指定上传文件保存路径
  • UPLOADED_FILES_URL:指定上传文件的URL
  • UPLOADED_FILES_ALLOW:指定允许上传的文件
  • UPLOAD_FILES_DENY:指定不允许上传的文件

注意:Flask-Uploads 可以设置不同的set ,所以以上FILES 的名称不是绝对的,而是指定UploadSet(name='FILES')  的name字段.这个名称可以根据自己上传文件的不同,而指定不同的名称,比如:如果是图片可以随意命名.

# config.pyUPLOADED_IMG_DEST=xxxUPLOADED_IMG_ALLOW=tuple('jpg jpe jpeg png gif svg bmp'.split())

# app.pyUploadSet(name='IMG')

UPLOADED_IMG_ALLOW=tuple('jpg jpe jpeg png gif svg bmp'.split()) 是自定义的文件类型的集合,也就是说,自定义文件类型必须是tuple类型,而且必须是以上格式.

Flask-Uploads中也有一些内置的类型:

TEXT = ('txt',)DOCUMENTS = tuple('rtf odf ods gnumeric abw doc docx xls xlsx'.split())IMAGES = tuple('jpg jpe jpeg png gif svg bmp'.split())AUDIO = tuple('wav mp3 aac ogg oga flac'.split())DATA = tuple('csv ini json plist xml yaml yml'.split())SCRIPTS = tuple('js php pl py rb sh'.split())ARCHIVES = tuple('gz bz2 zip tar tgz txz 7z'.split())EXECUTABLES = tuple('so exe dll'.split())DEFAULTS = TEXT + DOCUMENTS + IMAGES + DATA

通过导入即可使用,已经可以满足基本的使用.

from flask_uploads import TEXT,DOCUTMENTS,...
  • 如果对内置的类型中有些文件不允许上传,可以使用UPLOADED_X_DENY 来拒绝使用.
  • 如果要指定多种类型,可以使用UPLOADED_IMG_ALLOW=(IMGAGE+DOCUMENTS) 来扩展
  1. 文件名隐患

不用使用secure_filename() 来处理文件名,直接使用UploadSet().save(request.files.get('photo')) 方法来安全保存文件.photoinput 标签的name 元素.

  1. 限制文件大小
from flask_uploads import UploadSet,configure_uploads,patch_request_classpatch_request_class(app,32*1024*1024)

使用patch_request_class()  函数绑定app 来限制大小.

  1. 获取文件

UploadSet().url(filename) 函数可以获取上传文件的URL 路径,

3.UploadSet()

Flask-Uploads 的核心类

UploadSet(name='files', extensions=('txt', 'rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx', 'jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml'), default_dest=None)

photos = UploadSet('PHOTO')

它包含3个参数

  • name :指定文件上传Set 的集合,需要配合config.py 文件中的UPLOADED_X_DESTX字段
  • extensions:指定上传类型,可以被config.py 中的UPLOADED_X_ALLOWUPLOADED_X_DENY覆盖.
  • default_dest:指定上传的路径,可以被config.py 中的UPLOADED_X_DEST覆盖

注册配置好的UploadSet() 要使用方法config_uploads(app, photos)

4.Demo

$ treefile_upload_2├── app.py├── config.py├── static├── templates│   ├── show.html│   └── upload.html└── uploads    └── test.doc

upload.html

    <form action="" method="post" enctype="multipart/form-data">        <table>            <tr>                <td>上传文件td>                <td><input type="file" name="photo">td>            tr>            <tr>                <td><label for="#"><input type="submit">label>td>            tr>        table>    form>

show.html

<img src="{{ url }}" alt="{{ name }}">

config.py

import osfrom flask_uploads import IMAGES,DOCUMENTS

DEBUG=TrueTEMPLATES_AUTO_RELOAD=TrueDir = os.path.dirname(os.path.abspath(__file__))# 指定上传目录UPLOADED_PHOTO_DEST=Dir+'/uploads/'# 指定运行文件类型# IMAGES = tuple('jpg jpe jpeg png gif svg bmp'.split())UPLOADED_PHOTO_ALLOW=(IMAGES+DOCUMENTS)

app.py

from flask import Flask,request,redirect,url_for,render_template,abortfrom flask_uploads import UploadSet,configure_uploads,patch_request_classimport config

app = Flask(__name__)app.config.from_object(config)

@app.route('/')def hello_world():    return 'Hello World!'

# 限定上传文件大小patch_request_class(app,32*1024*1024)

# 约束上传文件类型和位置photos = UploadSet('PHOTO')# 注册到app中configure_uploads(app, photos)

@app.route('/uploads/',methods=['GET','POST'])def upload():    if request.method == 'POST' and 'photo' in request.files:        filename = photos.save(request.files.get('photo'))        return redirect(url_for('show',name=filename))    return render_template('upload.html')

@app.route('/uploads/',methods=['GET','POST'])def show(name):    if name is None:        return abort(404)    # 通过url 方法获取到文件的 URL路径    url = photos.url(name)    return render_template('show.html',url=url,name=name)

if __name__ == '__main__':    app.run()

- END -

antd upload手动上传_Flask上传文件相关推荐

  1. antd upload手动上传_antd 手动上传文件

    先说我要实现的效果:我想用antd 的 upload 实现手动上传文件,上传文件时还有附加参数 我看了官网上说在beforeUpload中返回false,然后通过按钮点击事件触发上传. Q1:附加参数 ...

  2. antd upload手动上传_SpringBoot 如何上传大文件?

    最近遇见一个需要上传超大大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  3. antd upload手动上传_基于MVVCTP5的文件上传

    现如今在市面上常见的web开发理念一般是两种,一种是MVC格式的,比较传统,而项目较大的开发,一般由团队完成,而MVC格式就显得有些不够合理 .于是 ,在这种情况下诞生了另外一种开发理念,我们叫MVV ...

  4. antd Upload手动上传(react)

    情况介绍 在antd官方提供的upload组件案例中,都使用了action属性直接上传,唯一手动上传的一个例子(如下图)也不够好用,可能不能满足项目的需求,所以我们需要对其进行一些修改,并加入一些别的 ...

  5. antd pro项目中 antd Upload组件 基于 lrz 在上传前做图片压缩

    lrz npm和参数文档可供参考 import { Upload,Button} from 'antd'; import lrz from 'lrz';//处理函数 function compress ...

  6. antd Upload 自定义上传

    需求 由于使用antd 上传图片,在某些情况下,例如token 失效,导致上传图片错误,但是antd 组件始终会走onChange 事件 导致上传路径为空情况 解决办法 使用自定义上传 // 自定义上 ...

  7. Upload手动上传文件

    Upload上传文件有两种方式: 1.自动上传,即在选择文件后就立即调用后台接口: 自动上传需要在action中写入请求接口,然后再方法里面写入回调函数即可 2.手动上传,即在选择好文件之后不会立即上 ...

  8. antd Upload组件上传状态一直处于uploading

    antd Upload组件上传状态一直处于uploading 对于受控模式,需要在 onChange 中始终 setState fileList,保证所有状态同步到 Upload 内 import { ...

  9. 【Antd Design Upload】 antd Upload 上传时只有Uploading状态,无法获取返回的数据

    问题:antd Upload 上传时只触发Uploading状态,无法获取服务器返回的response,根据控制台的结果发现只有一种Uploading,上传图片时只触发了一次. 根据官网可以知道.上传 ...

最新文章

  1. pythonmainoffset_python之(22)基础总结(5)
  2. 【原】a.class与a .class的区别
  3. 两部手机怎样才能把数据都传过来_我把魅族换成荣耀,30G的数据文件该如何一键转移?...
  4. 递推(hdu2563)
  5. RNN 循环神经网络系列 5: 自定义单元
  6. 关于Python中的classmethod
  7. Linux下的段错误产生的原因及调试方法
  8. 搭建国外海外多语言一元云购软件夺宝购商城网站
  9. React Native集成阿里云推送----广播推送
  10. 电脑版微信公众号文章加载不出来,空白的可能解决办法
  11. 解决SVN造成的桌面图标问号
  12. vue中如何在搜索框中实现关键字搜索
  13. 图像处理:Yxy、XYZ颜色空间介绍及RGB转换公式
  14. CISP-PTE靶机练习(me-and-my-girlfriend)
  15. vue 跳转页面删除当前tab
  16. 从yield到yield from
  17. 带后台管理的超酷jquery+ajax幻灯相册php源码,仿门户网图片频道的jQuery幻灯相册轮播代码...
  18. Freeswitch挂断原因汇总
  19. 2021-2025年中国4K和8K超高清电视行业市场供需与战略研究报告
  20. 掌握JavaScript

热门文章

  1. docker中部署Tomcat
  2. centos7完全卸载删除nginx
  3. mag6000变送器怎么使用_变送器的迁移原理和故障分析
  4. Navicat Premium 15连接SQL sever (记录一下我的艰难历程,希望对大家有用,摸了半天终于连接上了)
  5. 计算机二级考试基础知识总结,全国计算机等级考试二级公共基础知识总结
  6. Java双向链表快速排序_双向链表的插入,删除,以及链表的快速排序
  7. Qt / 伪状态和子部件
  8. C typedef功能介绍(内附函数指针和指针函数的区别)
  9. python循环捕捉异常_python异常捕捉以及处理
  10. micropython是啥 知乎_micropython入门教程