Carlos G. Oliver
Carlos G. Oliver

Reputation: 335

Flask form to receive text box and file upload

I have an HTML form in my /templates that takes a text query and a file upload as input.

HTML

    <form action="/submitted" enctype=multipart/form-data method="POST" onsubmit="showDiv('loading')">
      <input type="text" name="query" size="50" required><br>
      <input type="file" id="fileSelect" name="file" accept=".csv">
      <input type="submit" id="query_submit">
   </form>

Saving the file works from flask when the enctype is set to multipart/form-data but accessing request.form causes a 400 error which I read is due to a missing key error. And vice versa, if I remove the enctype, I get a 400 error but the request.form which contains the query is accessible.

@app.route("/submitted", methods=['POST', 'GET'])
def submitted():
    if request.method == 'POST':
        result = request.form

        query = result['query']

        if not result['file']:
            datapath = 'static/iris.csv'
            plot_id = str(uuid.uuid1())
        else:
            f = request.files['file']
            f.save(secure_filename(f.filename))
            filename = secure_filename(f.filename)
            f.save(os.path.join(app.config['UPLOAD_FOLDER'],\
                     filename))

        return render_template("submitted.html")

What is the proper way to read multiple input types (text, file) in the same form? Or should I make a separate form for the file?

Thanks!

Upvotes: 2

Views: 5843

Answers (2)

Carlos G. Oliver
Carlos G. Oliver

Reputation: 335

I found the problem. It was when trying to access request.form['file'] to check if there was no file uploaded. With a form that accepts a file, for some reason that is a key error. So instead I use request.files to check for missing file. Here is a working /submitted function.

@app.route("/submitted", methods=['POST', 'GET'])
def submitted():
    if request.method == 'POST':
        result = request.form

        query = result['query']

        if 'file' not in request.files:
            datapath = 'static/iris.csv'
            plot_id = str(uuid.uuid1())
        else:
            f = request.files['file']
            f.save(secure_filename(f.filename))
            filename = secure_filename(f.filename)
            f.save(os.path.join(app.config['UPLOAD_FOLDER'],\
                     filename))

        return render_template("submitted.html")

Upvotes: 1

Vishwanath Seshagiri
Vishwanath Seshagiri

Reputation: 41

In your function for the route /submitted, you need to receive the files using the function request.files, and the regular data using request.form.get

Upvotes: 2

Related Questions