flask上传文件(图片)

本文详细介绍了如何使用原生HTML和Flask实现文件上传功能,包括上传表单的设计、文件处理逻辑、缩略图生成及flask-uploads库的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原生上传文件

  1. 添加一个模板文件

    <html>
    <head>
        <title>原生文件上传</title>
    </head>
    <body>
        {% if img_url %}
            <img src="{{ img_url }}">
        {% endif %}
        <form method="post" enctype="multipart/form-data">   #上传文件必须提交
            <input type="file" name="photo" />
            <input type="submit" value="上传" />
        </form>
    </body>
    </html>
    
  2. 添加视图函数

    @app.route('/upload/', methods=['GET', 'POST'])
    def upload():
        img_url = None
        if request.method == 'POST':
            file = request.files.get('photo')  #获取文件对象
            if file and allowed_file(file.filename):
                # 获取文件后缀
                suffix = os.path.splitext(file.filename)[1]
                # 生成随机文件名
                filename = random_string() + suffix
                # 保存上传文件
                file.save(os.path.join(app.config['UPLOAD_FOLDER'], 
                                       filename))
                # 构造上传的文件的访问URL
                img_url = url_for('uploaded', filename=filename)
        return render_template('upload.html', img_url=img_url)
    
  3. 相关配置及函数

    # 允许上传的文件后缀
    ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
    # 配置上传文件保存位置
    app.config['UPLOAD_FOLDER'] = os.getcwd()
    # 上传文件大小
    app.config['MAX_CfONTENT_LENGTH'] = 1024 * 1024 * 8
    
    # 判断是否是允许的文件后缀
    def allowed_file(filename):
        return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
    
    # 生成随机的字符串
    def random_string(length=32):
        import random
        base_str = 'abcdefghijklmnopqrstuvwxyz1234567890'
        return ''.join(random.choice(base_str) for i in range(length))
    
    # 获取上传文件
    @app.route('/uploaded/<filename>')
    def uploaded(filename):
        # 安全的发送文件
        return send_from_directory(app.config['UPLOAD_FOLDER'], 
                                   filename)
    
  4. 注意事项,文件上传失败时,应从哪些方面着手

    1.表单的提交方法必须是POST
    2.表单的enctype属性必须设置为multipart/form-data
    3.上传的字段类型必须为file,并且必须有name属性
    4.是否超过运行的最大尺寸
    5.文件的保存位置是否有空间,是否有权限
    
  5. 生成缩略图,需要安装pillow库 pip install pillow

    # 导入图片处理的类,默认PIL不支持python3.x,安装pillow后就可以了
    from PIL import Image
    
    # 生成缩略图
    # 1.打开文件
    img = Image.open(pathname)
    # 2.重设尺寸
    img.thumbnail((128, 128))
    # 3.保存修改
    img.save(pathname)
    

flask-uploads

  1. 说明:在文件上传时,提供了很大的方便,如:文件类型的过滤,校验等

  2. 安装:pip install flask-uploads

  3. 使用:

    相关配置:

    # 上传文件的大小
    app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8
    # 上传文件的保存位置
    app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd()
    
    # 创建上传对象,指定过滤的文件后缀
    photos = UploadSet('photos', IMAGES)
    configure_uploads(app, photos)
    # 配置上传文件大小,默认64M,设置为None时使用MAX_CONTENT_LENGTH选项
    patch_request_class(app, size=None)  #去除默认设置
    

    视图函数:

    @app.route('/upload/', methods=['GET', 'POST'])
    def upload():
        img_url = None
        if request.method == 'POST' and 'photo' in request.files:
            # 保存文件
            filename = photos.save(request.files['photo'])
            # 获取保存文件的url
            img_url = photos.url(filename)
        return render_template('upload.html', img_url=img_url)
    

    模板文件:同原生的文件上传upload.html

    from werkzeug.utils import secure_filename#由from werkzeug import secure_filename,EileStorage改成现在的情况from werkzeug.datastructuresimport FileStorage

完整的文件上传

  1. flask-uploads配置同上

  2. flask-wtf配置

    # 导入表单基类
    from flask_wtf import FlaskForm
    # 导入文件上传字段及验证器
    from flask_wtf.file import FileField, FileRequired, FileAllowed
    from wtforms import SubmitField
    
    # 上传文件表单类
    class UploadForm(FlaskForm):
        'srace' = FileField('头像上传', 
                     validators=[FileRequired('文件未选择'), 
                     FileAllowed(photos, message='只能上传图片文件')])
        submit = SubmitField('上传')
    
  3. 视图函数:

    @app.route('/upload/', methods=['GET', 'POST'])
    def upload():
        img_url = None
        form = UploadForm()
        if form.validate_on_submit():
            # 获取文件后缀
            suffix = os.path.splitext(form.photo.data.filename)[1]
            # 生成所及文件名
            filename = random_string() + suffix
            # 保存上传文件
            photos.save(form.photo.data, name=filename)
            # 生成缩略图
            pathname = os.path.join(app.config['UPLOADED_PHOTOS_DEST'], 
            						filename)
            # 打开文件
            img = Image.open(pathname)
            # 设置尺寸
            img.thumbnail((128, 128))
            # 保存文件
            img.save(pathname)
            # 获取上传文件的url
            img_url = photos.url(filename)
        return render_template('upload.html', form=form, img_url=img_url)
    
  4. 模板文件upload.html

    {% extends 'bootstrap/base.html' %}
    
    {% import 'bootstrap/wtf.html' as wtf %}
    
    {% block content %}
        <div class="container">
            {% if img_url %}
                <img src="{{ img_url }}" />
            {% endif %}
            {{ wtf.quick_form(form) }}
        </div>
    {% endblock %}
    

代码运行过程如下:
在这里插入图片描述
app.py里面的代码如下:


import os
from flask import Flask,render_template,request
from flask_script import Manager
app = Flask(__name__)
#指定上传的路径
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__),'static')
#允许上传的文件名后缀
ALLOWED_EXTENSIONS = set(['png','jpg','jpeg','gif'])

#限定上传文件大小  8M
app.config['MAX_CONTENT_LENGTH'] = 8 * 1024 * 1024

manager= Manager(app)

#判断是否是允许的后缀 manba.jpg
def allow_file(filename):
    return '.' in filename and filename.rsplit('.',1)[1] in ALLOWED_EXTENSIONS

print(allow_file('canglaoshi.jpg'))

#生成随机字符串
def random_string(length=16):
    import random
    base_str = '0987654321qwertyuiopasdfghjklzxcvbnm'
    return "".join(random.choice(base_str) for i in range(length))
    # import string
    # source = list(string.ascii_letters)
    # for index in range(0,10):
    #     source.append(str(index))
    # print(source)
    # return source





@app.route('/',methods=['GET','POST'])
def hello_world():
    # request.args[]  #get请求参数
    # request.form[]  #post 请求参数
    # request.files
    if request.method == 'POST':
        file = request.files.get('photo')
        if file and allow_file(file.filename):
            #获取后缀名
            surfix = os.path.splitext(file.filename)[1]
            # 新的文件名
            filename = random_string() + surfix
            file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
    # print(os.path.join(os.path.dirname(__file__),'upload'))
    return render_template('index.html')


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

index.html里面的代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>原生文件上传</h1>
    <form action="" enctype="multipart/form-data" method="post">
        <input type="file" name="photo" />
        <input type="submit" value="立即上传">
    </form>
</body>
</html>

回到app.py文件,下面输入:
python app.py runserver -d -r -p 5050
回车,点击地址进入:
在这里插入图片描述
点击选择文件:
在这里插入图片描述
选中某个图片进行上传,保存到static文件里面:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值