使用Flask上传文件

时间:2018-03-12 22:34:57

标签: python-3.x file-upload flask

我正在Flask中构建一个表单中有2个FileFields的表单,但是,除非我使用wtf.quick_form来呈现我的html页面,否则我无法上传文件。

我尝试将文件上传放到类中以便可以重复使用,但是,字段数据是作为字符串传递的。

我的代码:

from flask import Flask, render_template, flash, request
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
import wtforms.validators

from flask import Flask, request, url_for, redirect
from werkzeug.utils import secure_filename

import os

class ChangeForm(FlaskForm):

    bizAuth = FileField('Additional Sign-off:')
    newDoc = FileField('Training/Documentation')
    submit = SubmitField('Save')


@app.route('/change', methods=['GET','POST'])
def form():

    if chgForm.validate_on_submit():

        fUp = File_Upload() # File Upload class - detailed below.
        chgForm = ChangeForm()

        bizAuth = chgForm.bizAuth.data
        chgDetail['bizAuth'] = fUp.upload(bizAuth)

        newDoc = chgForm.newDoc.data
        chgDetail['newDoc'] = fUp.upload(newDoc)


class File_Upload():

    def allowed_files(self, fileName):

        ALLOWED_EXTENSIONS = self.allowed_files_lookup()

        return '.' in fileName and fileName.rsplit('.',1)[1].lower() in ALLOWED_EXTENSIONS

    def upload(self, fileName):

        f = fileName.filename

        if f == '':
            return 'NULL'

        elif f and self.allowed_files(f):

            file = secure_filename(f)
            fileName.save(os.path.join(config['src_dir'],'Normal Changes Docs\\' + f))

        return str(os.path.join(config['src_dir'],'Normal Changes Docs\\' + f))

我的HTML:

 <!DOCTYPE html>
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="{{ url_for('static', filename='chgForm-hiding.css') }}">

    {% block title %}Change Process{% endblock %}

</head>

 <body>

{% block page_content %}
    <form>
        <div class="Biz_Auth">
            {{form.bizAuth.label}}
            {{form.bizAuth}}
        </div>

        <div class="new-doc">
            {{form.newDoc.label}}
            {{form.newDoc}}
        </div>
        {{form.submit}}
    </form>
{% endblock %}

</body>

如果有人可以提供帮助,我将非常感激。我所看到的许多示例都没有以我的方式将上传功能分开,而是依靠使用quick_form将页面或特定的html标签硬编码到其上传功能中。

1 个答案:

答案 0 :(得分:2)

需要进行以下更改:

更改1

if request.method == "POST" and chgForm.validate_on_submit():
    bizAuth = chgForm.bizAuth.data
    chgDetail['bizAuth'] = fUp.upload(bizAuth)

    newDoc = chgForm.newDoc.data
    chgDetail['newDoc'] = fUp.upload(newDoc)

更改2

<form action="{{ url_for('form') }}" method="post" enctype="multipart/form-data">

更改3

在表单标记{{ form.csrf_token }}

中添加以下内容

下面是一个带有上述更改的示例python脚本,

app.py

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
from flask import request
import os

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './uploads'
app.config['SECRET_KEY'] = 'catchmeifyoucan'


class ChangeForm(FlaskForm):
    bizAuth = FileField('Additional Sign-off:')
    newDoc = FileField('Training/Documentation')
    submit = SubmitField('Save')


@app.route('/change', methods=['GET','POST'])
def form():
    fUp = FileUpload()  # File Upload class - detailed below.
    chgForm = ChangeForm()
    chgDetail = dict()

    # Change 1
    if request.method == "POST" and chgForm.validate_on_submit():
        bizAuth = chgForm.bizAuth.data
        chgDetail['bizAuth'] = fUp.upload(bizAuth)

        newDoc = chgForm.newDoc.data
        chgDetail['newDoc'] = fUp.upload(newDoc)

    return render_template('index.html', form=chgForm)


class FileUpload():

    def allowed_files(self, file_name):
        allowed_extensions = ['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']
        return '.' in file_name and file_name.rsplit('.',1)[1].lower() in allowed_extensions

    def upload(self, file):
        file_name = file.filename
        if file_name == '':
            return 'NULL'

        elif file_name and self.allowed_files(file_name):
            secure_file_name = secure_filename(file_name)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'],'Normal Changes Docs\\' + secure_file_name))

        return str(os.path.join(app.config['UPLOAD_FOLDER'],'Normal Changes Docs\\' + secure_file_name))


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

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sample</title>
</head>
<body>
<form action="{{ url_for('form') }}" method="post" enctype="multipart/form-data">
    {{ form.csrf_token }}
    {{ form.bizAuth.label }}
    {{ form.bizAuth }}
    {{ form.newDoc.label }}
    {{ form.newDoc }}
    {{ form.submit }}
</form>
</body>
</html>

我希望这会有所帮助。