Flask框架上传和下载文件

这篇具有很好参考价值的文章主要介绍了Flask框架上传和下载文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、Flask上传文件

上传文件步骤

1. 在模版html中,表单需要指定 enctype='multipart/form-data' 才能上传文件。

2. 在后台如果想要获取上传的文件,那么应该使用 request.files.get('文件名') 来获取。

3. 保存文件之前,先要使用 werkzeug.utils.secure_filename 来对上传上来的文件名进行一个过滤。能保证不会有安全问题。

4. 获取到上传上来的文件后,使用 文件对象.save(路径) 方法来保存文件。路径=完整路径=路径名+文件名

示例代码:

main.py

from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os


app = Flask(__name__)
UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'images')


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


@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        img_file = request.files.get('pic')
        file_name = img_file.filename
        # 文件名的安全转换
        filename = secure_filename(file_name)
        # 保存文件
        img_file.save(os.path.join(UPLOAD_PATH, filename))
        return '上传文件成功!'


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

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/upload/" method="post" enctype="multipart/form-data">
        上传文件:<input type="file" name="pic"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

运行结果:

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

系统路径中生成的文件:

flask send_file,Flask框架,python,flask,send_file

2、Flask下载文件

2.1 send_from_directory方法

从服务器上读取文件,应该定义一个url与视图函数,来获取指定的文件。

在这个视图函数中,使用 send_from_directory(文件的目录,文件名) 来获取。

send_from_direction函数底层实现:

def send_from_directory(directory, filename, **options):
    """Send a file from a given directory with :func:`send_file`.  This
    is a secure way to quickly expose static files from an upload folder
    or something similar.

    Example usage::

        @app.route('/uploads/<path:filename>')
        def download_file(filename):
            return send_from_directory(app.config['UPLOAD_FOLDER'],
                                       filename, as_attachment=True)

    .. admonition:: Sending files and Performance

       It is strongly recommended to activate either ``X-Sendfile`` support in
       your webserver or (if no authentication happens) to tell the webserver
       to serve files for the given path on its own without calling into the
       web application for improved performance.

    .. versionadded:: 0.5

    :param directory: the directory where all the files are stored.
    :param filename: the filename relative to that directory to
                     download.
    :param options: optional keyword arguments that are directly
                    forwarded to :func:`send_file`.
    """
    filename = fspath(filename)
    directory = fspath(directory)
    filename = safe_join(directory, filename)
    if not os.path.isabs(filename):
        filename = os.path.join(current_app.root_path, filename)
    try:
        if not os.path.isfile(filename):
            raise NotFound()
    except (TypeError, ValueError):
        raise BadRequest()
    options.setdefault("conditional", True)
    return send_file(filename, **options)

示例代码:

目前服务器中存在的文件:

flask send_file,Flask框架,python,flask,send_file

from flask import Flask, send_from_directory
import os


app = Flask(__name__)
UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'images')


@app.route('/download/<string:filename>/')
def download_file(filename):
    return send_from_directory(UPLOAD_PATH, filename)
    # return send_from_directory(UPLOAD_PATH, filename, as_attachment=True)


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

运行结果:

flask send_file,Flask框架,python,flask,send_file

当参数as_attachment=True时:

flask send_file,Flask框架,python,flask,send_file

2.2 send_file方法

send_file()函数:

def send_file(
    path_or_file: t.Union[os.PathLike, str, t.BinaryIO],
    mimetype: t.Optional[str] = None,
    as_attachment: bool = False,
    download_name: t.Optional[str] = None,
    attachment_filename: t.Optional[str] = None,
    conditional: bool = True,
    etag: t.Union[bool, str] = True,
    add_etags: t.Optional[bool] = None,
    last_modified: t.Optional[t.Union[datetime, int, float]] = None,
    max_age: t.Optional[
        t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]]
    ] = None,
    cache_timeout: t.Optional[int] = None,
):

参数解析:

  • path_or_file:要发送的文件的路径,如果给出了相对路径,则相对于当前工作目录。或者,以二进制模式打开的类文件对象。确保将文件指针查找到数据的开头。
  • mimetype:为文件发送的MIME类型。如果没有提供,它将尝试从文件名检测它。
  • as_attachment:指示浏览器应该提供给保存文件而不是显示它。
  • download_name:浏览器保存文件时使用的默认名称。默认为传递的文件名。
  • conditional:基于请求头启用条件响应和范围响应。需要传递一个文件路径和``environ``。
  • etag:计算文件的etag,这需要传递一个文件路径。也可以是字符串来代替。
  • last_modified:发送文件的最后修改时间,单位为秒。如果没有提供,它将尝试从文件路径检测它。
  • max_age:客户端应该缓存文件多长时间,以秒为单位。如果设置,' ' Cache-Control ' '将为' ' public ' ',否则将为' ' no-cache ' '以选择条件缓存。

注意:

flask send_file,Flask框架,python,flask,send_file

示例代码:

import os
from flask import Flask, send_file, request, render_template, redirect
from werkzeug.utils import secure_filename

app = Flask(__name__)


UPLOAD_FOLDER = 'media'  # 注意:要提前在根目录下新建media文件,否则会报错
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


# 判断上传的文件是否是允许的后缀
def allowed_file(filename):
    return "." in filename and filename.rsplit('.', 1)[1].lower() in set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])


@app.route('/')
def index():
    return "hello world!"


@app.route('/generate_file')
def generate_file():
    with open('./new_file.txt', 'w', encoding='utf-8') as f:
        f.write('我是new_file.txt文件!')
    return "<./new_file.txt>文件已经生成!"


@app.route('/download')
def download():
    return send_file('./new_file.txt', as_attachment=True)


@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        if "file" not in request.files:
            return redirect(request.url)

        file = request.files.get('file')  # 获取文件

        # 上传空文件(无文件)
        if file.filename == '':
            return redirect(request.url)

        if file and allowed_file(file.filename):
            if not os.path.exists(f'./templates/{UPLOAD_FOLDER}'):
                os.mkdir(f'./templates/{UPLOAD_FOLDER}')
            filename = secure_filename(file.filename)  # 用这个函数确定文件名称是否是安全 (注意:中文不能识别)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))  # 保存文件
            return "上传文件成功!"


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

下载和上传路径中可以添加用户身份验证:

import os
from flask import Flask, send_file, request, render_template, redirect
from werkzeug.utils import secure_filename

app = Flask(__name__)


UPLOAD_FOLDER = 'media'  # 注意:要提前在根目录下新建media文件,否则会报错
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
allow_users = ['dgw', 'super_user']


# 判断上传的文件是否是允许的后缀
def allowed_file(filename):
    return "." in filename and filename.rsplit('.', 1)[1].lower() in set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])


@app.route('/')
def index():
    return "hello world!"


@app.route('/generate_file')
def generate_file():
    with open('./new_file.txt', 'w', encoding='utf-8') as f:
        f.write('我是new_file.txt文件!')
    return "<./new_file.txt>文件已经生成!"


@app.route('/download')
def download():
    user_name = request.args.get('user_name')
    if not user_name:
        return "你没有权限下载文件!"
    if user_name and user_name not in allow_users:
        return "你没有权限下载文件!"
    return send_file('./new_file.txt', as_attachment=True)


@app.route('/upload/<string:user_name>', methods=['GET', 'POST'])
def upload(user_name):
    if request.method == 'GET':
        if user_name not in allow_users:
            return "您没有权限访问此页面!"
        return render_template('upload.html')
    else:
        if user_name not in allow_users:
            return "您没有权限访问此页面!"

        if "file" not in request.files:
            return redirect(request.url)

        file = request.files.get('file')  # 获取文件

        # 上传空文件(无文件)
        if file.filename == '':
            return redirect(request.url)

        if file and allowed_file(file.filename):
            if not os.path.exists(f'./templates/{UPLOAD_FOLDER}'):
                os.mkdir(f'./templates/{UPLOAD_FOLDER}')
            filename = secure_filename(file.filename)  # 用这个函数确定文件名称是否是安全 (注意:中文不能识别)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))  # 保存文件
            return "上传文件成功!"


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

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="上传">
</form>
</body>
</html>

3、Flask-wtf验证上传的文件

关键点:

  1. 定义验证表单类的时候,对文件类型的字段,需要采用 FileField 这个类型,即wtforms.FileField
  2. 验证器需要从 flask_wtf.file 中导入。 flask_wtf.file.FileRequired 和 flask_wtf.file.FileAllowed
  3. flask_wtf.file.FileRequired 是用来验证文件上传不能为空。
  4. flask_wtf.file.FileAllowed 用来验证上传的文件的后缀名, 如常见图片后缀 .jpg 和.png以及.gif等。
  5. 在视图函数中,需要使用 from werkzeug.datastructures import CombinedMultiDict 来把request.form 与 request.files 来进行合并。
  6. 最后使用 表单验证对象.validate()进行验证。

示例代码:

main.py

from flask import Flask, render_template, request
from werkzeug.datastructures import CombinedMultiDict
from werkzeug.utils import secure_filename
import os
from formcheck import UpLoadForm

app = Flask(__name__)
UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'images')


@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        form = UpLoadForm(CombinedMultiDict([request.form, request.files]))
        if form.validate():
            img_file = form.pic.data
            file_name = secure_filename(img_file.filename)
            img_file.save(os.path.join(UPLOAD_PATH, file_name))
            return '上传文件成功!'
        else:
            return f'{form.errors}'


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

formcheck.py

from wtforms import Form, FileField
from flask_wtf.file import FileAllowed, FileRequired


class UpLoadForm(Form):
    pic = FileField(validators=[FileRequired(), FileAllowed(['jpg', 'png', 'gif'])])

upload.py

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/upload/" method="post" enctype="multipart/form-data">
        上传文件:<input type="file" name="pic"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

运行结果:

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

flask send_file,Flask框架,python,flask,send_file

参考博文:

Python Flask 文件下载_flask下载_liyinchi1988的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-787238.html

到了这里,关于Flask框架上传和下载文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flask Web API构建实例:GET、POST文件上传、静态资源下载一网打尽

      以下是一个通过 Flask 构建 Web API 服务的详细示例,包含了各类请求(GET、POST、文件上传、静态资源下载)、每个方法独立配置路由、参数接收和解析、请求日志记录以及异常日志记录。请确保你已经安装了 Flask,你可以使用以下命令进行安装: 接下来是一个包含详细注释

    2024年02月04日
    浏览(52)
  • 如何把本地flask项目(框架)上传到服务器(Linux),并后台持续运行(包括requirements文件生成,python项目与域名绑定,保姆级教程)

     2023年中旬,参加了一个比赛,需要搭建一个网站。在不断探索琢磨之后,搭建了一个基于flask的web。直接上干货: 一、首先,在本地准备好自己的flask项目。包括最基本的三个文件: 然后准备生成requirements.txt文件,这个文本文件会告诉服务器你的项目运行所需要的环境,即

    2024年02月04日
    浏览(48)
  • Flask 文件上传,删除上传的文件

     目录结构  app.py templates / index.html 效果图

    2024年02月15日
    浏览(44)
  • Flask boostrap实现图片视频上传下载展示

    项目目录结构 html js代码 fileinput插件下载地址:https://github.com/kartik-v/bootstrap-fileinput/ imgEnlarge.js如下 代码下载链接:https://download.csdn.net/download/weixin_44986037/87986647

    2024年02月12日
    浏览(41)
  • Flask 上传文件,requests通过接口上传文件

    这是一个使用 Flask 框架实现文件上传功能的示例代码。该代码定义了两个路由: /upload :处理文件上传请求。在该路由中,我们首先从请求中获取上传的文件,然后将文件保存到本地磁盘上,并返回一个字符串表示上传成功。 / :返回一个 HTML 表单,用于选择文件并提交上传

    2024年02月08日
    浏览(35)
  • 【Python】Web学习笔记_flask(3)——上传文件

    用GET、POST请求上传图片并呈现出来 首先还是创建文件上传的模板 然后需要定义几个函数: upload():路由函数,接收GET请求时,显示模板文件内容,接收post请求时,上传图片 allowed_file():检测上传的文件是否满足设置的类型 random_file():为上传的文件重新创建随机的不重复文

    2024年02月14日
    浏览(43)
  • flask项目中 实现下载文件功能

    file_path 变量中提供要下载的文件的路径。 当访问 download 路由时,会触发 download_file 函数,该函数使用 send_file 方法将文件发送到客户端以进行下载 as_attachment=True 表示将文件作为附件下载,而不是在浏览器中直接打开。

    2024年02月07日
    浏览(50)
  • 用element ui上传带参数的文件,并用flask接收

    网页需要实现上传一个csv文件,并携带两个表单的参数给后端

    2024年02月03日
    浏览(43)
  • Flask下载文件报错304 NOT MODIFIED

    前端 Vue 下下来的文件无法正常打开,大小比正常的略大一点,通过 Postman 直接调用是正常的 由前端解决 如果响应大小比文件略大一点,从 responses 中取出关键数据再组成文件 如果响应大小很小,例如七百多B, 删掉请求头中的 If-None-Match和If-Modified-Since HTTP缓存和浏览器的本

    2024年02月12日
    浏览(42)
  • 阿桂天山的技术小结:Flask+UEditor实现图片文件上传富文本编辑

    话不多说,有图有源码 先看效果:  1.前端html页面index.html 2.后端ueditor.py执行文件( 这个非常重要 ) 3.路径配置文件config.py 4.启动运行程序appstart.py 特殊强调 :路径蓝图,必须指向ueditor( 这个非常非常非常重要,否则前端会报错 ),放在app执行文件中 5)最后整个工程文件树:    希望你

    2024年02月11日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包