Christopher Nelson
Christopher Nelson

Reputation: 1017

Bad Request with Flask

really struggling with this bad request from flask. I know normally it caused by flask not finding the [key] in the form.. However, I've checked my form and python code 40 times and cannot see any reason that would be the case.. I have commented out each line of the python code that references request.form. I have done it 1 by 1 and I still get a bad request. However when I comment out all the lines the bad request goes away.. Any thought would be wonderful..

Python code;

if request.method == 'POST':
    form = 'Add Package Form'
    clientId = request.form['id']
    date = request.form['date2']
    strPrice = request.form['price']
    price = float(strPrice)
    adultlessons = request.form['adult']
    juniorlessons = request.form['junior']
    shortlessons = request.form['short']
    playinglessons = request.form['playing']
    notes = request.form['notes']

form..

<form action="/addpackage" method="post" class="sky-form">
                <fieldset>
                <section>
                    <label class="label">Select Package Date</label>    
                    <label class="input">
                        <i class="icon-append fa fa-calendar"></i>
                        <input type="text" name="date2" id="date">
                    </label>
                </section>
                <div style="margin: -25px"></div>
            <fieldset>
                <section>
                    <label class="label">Price</label>
                    <label class="input">
                        <input type="text" name="price">
                    </label>
                </section>
                <section>
                    <label class="label">Adult Lessons</label>
                    <label class="input">
                        <input type="text" name="adult">
                    </label>
                </section>
                <section>
                    <label class="label">Junior Lessons</label>
                    <label class="input">
                        <input type="text" name="junior">
                    </label>
                </section>
                <section>
                    <label class="label">Short Game Lessons</label>
                    <label class="input">
                        <input type="text" name="short">
                    </label>
                </section>
                <section>
                    <label class="label">Playing Lessons</label>
                    <label class="input">
                        <input type="text" name="playing">
                    </label>
                </section>
                <section>
                    <label class="label">Notes</label>
                    <label class="textarea textarea-expandable">
                        <textarea rows="3" name="notes"></textarea>
                    </label>
                    <div class="note"><strong>Note:</strong> expands on focus.</div>
                </section>
            </fieldset>
                </fieldset>
            <!-- hidden client id -->
            <input type="hidden" name="id" value="{{ client.id }}">
            <!-- /hidden client id -->
            <footer>
                <button type="submit" name="addpackage" value="package" class="button">Add Package</button>
            </footer>
        </form>

Upvotes: 2

Views: 6684

Answers (3)

Grey Li
Grey Li

Reputation: 12762

You should give the form data a default value to avoid HTTP 400 error, like this:

default_value = True
is_public = request.form.get('public', default_value)

However, I recommend you to use Flask-WTF.
With Flask-WTF, your code can be simplify to this (an example):

import ...
app = Flask(__name__)

class EditProfileForm(Form):
    name = StringField('name', validators=[Length(0, 64)])
    location = StringField('city', validators=[Length(0,64)])
    website = StringField('website', validators=[Length(0,64), render_kw={"placeholder": "http://..."})
    about_me = TextAreaField('Bio', validators=[Length(0,2000)], render_kw={"placeholder": "I'm......"})
    submit = SubmitField(u'submit')

@app.route('/edit-profile', methods=['GET', 'POST'])
def edit_profile():
    form = EditProfileForm()
    if form.validate_on_submit():
        current_user.name = form.name.data
        current_user.location = form.location.data
        current_user.website = form.website.data
        current_user.about_me = form.about_me.data
        db.session.add(current_user)
        flash('Update success!', 'success')
        return redirect(url_for('.user', username=current_user.username))
    return render_template('edit_profile.html', form=form)

In your html file:

<form method="POST" action="/">
    {{ form.hidden_tag() }}
    {{ form.name.label }} {{ form.name() }}
    {{ form.location.label }} {{ form.location() }}
    ...
</form>

By the way, if you use Flask-Bootstrap, you can just use one line to render the whole form:

{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}

I hope it will help.

Upvotes: 0

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38922

Usually you'll get a 400 Bad Request in Flask while submitting a form when you try and access a form key in the request object that doesn't exist.

This is because the request.form object inherits its __getitem__ method the Multidict class in the werkzeug.datastructures module which raises a BadRequestKeyError when a key doesn't exist.

Upvotes: 2

larsks
larsks

Reputation: 311238

This is something of a half-answer, but it was too long for a comment.

If you enable debugging in your Flask app you should get a detailed traceback indicating exactly where the problem is occurring (both in the browser and on your console).

If your application currently has something like:

app.run()

Just set the debug parameter to true:

app.run(debug=True)

If after enabling debugging you're still not sure what's causing the problem, update your question to include the traceback.

For what it's worth, if I dump your form and your code into a simple Flask app, it all seems to work just fine as long as I provide a numeric value for the price field.

Upvotes: 2

Related Questions