python-flask html form help/suggestions
<p>I'm rendering a page for users to browse ad listings on a practice site. On the 'browse' page, I have three separate forms, two are select fields and the other is a textfield. The select fields allow a user to change location or transaction type, and the text field allows them to change the thing they are searching for. I wanted to do this pure HTML and not use flask-wtf. I have successfully got the part where they can change location working, but as soon as I add code for the other options, it breaks and I get a <strong>400 bad request error</strong>. Any suggestions or guidance as to why this is isn't working when I add in the forms for changing item and transaction type?</p>

<pre><code> @app.route('/find-it/', methods=['GET','POST'])
def browse():
   try:

    location = session.get('location', None)
    transType = session.get('transType', None)
    item = session.get('item', None)        

    data = browseQuery()

     if request.method == 'POST':
        if request.form['changeLocation'] != '':
            print('location changed')
            location = request.form['changeLocation']
            session['location'] = location
            return redirect(url_for('browse', location=location))
        elif request.form['changeType'] != '':
            print('type changed')
            transType = request.form['changetype']
            session['transType'] = transType
            return redirect('browse', transType=transType)
        else:
            if request.form['changeItem'] != '':
                print('item changed')
                item = request.form['changeItem']
                session['item'] = item
                return redirect(url_for('browse', item=item))

      return render_template('all-classifieds.html',location=location,transType=transType, data=data)
except Exception as e:
    return (str(e))
</code></pre>

<p>HTML:</p>

<pre><code>&lt;form method="post" id="changeLocation" name="changeLocation" action=""&gt;

                    &lt;select name="changeLocation" id="changeLocation" style="margin-right: 5%; float: left;"&gt;
                        &lt;optgroup label="Where?"&gt;
                            &lt;option selected style="display:none;color:#eee;"&gt;&lt;/option&gt;
                            &lt;option&gt;option 1&lt;/option&gt;
                            &lt;option&gt;option 2&lt;/option&gt;

                        &lt;/optgroup&gt;&lt;/select&gt;&lt;/form&gt;


&lt;button type="submit" id="submit" form="changeLocation" style="padding: 0 3px; float:left;"
                        class="btn btn-info btn-sm"&gt;
                    &lt;i class="glyphicon glyphicon-search"&gt;&lt;/i&gt;
                &lt;/button&gt;




 &lt;form method="post" name="changeType" id="changeType"&gt;


                    &lt;select name="changeType" id="changeType" style="margin-right: 5%; float: left;"&gt;
                        &lt;optgroup label="..."&gt;
                            &lt;option selected style="display:none;color:#eee;"&gt;&lt;/option&gt;
                            &lt;option&gt;option 1&lt;/option&gt;
                            &lt;option&gt;option 2&lt;/option&gt;
                            &lt;option&gt;option 3&lt;/option&gt;

                        &lt;/optgroup&gt;
                    &lt;/select&gt;



&lt;form method="post" name="changeType" id="changeType"&gt;


                    &lt;select name="changeType" id="changeType" style="margin-right: 5%; float: left;"&gt;
                        &lt;optgroup label="Look for things that are..."&gt;
                            &lt;option selected style="display:none;color:#eee;"&gt;&lt;/option&gt;
                            &lt;option&gt;asdf&lt;/option&gt;
                            &lt;option&gt;asdfasdf&lt;/option&gt;
                            &lt;option&gt;asdfasdfasdf&lt;/option&gt;

                        &lt;/optgroup&gt;
                    &lt;/select&gt;&lt;/form&gt;

&lt;button type="submit" id="submit" form="changeType" style="padding: 0 3px; float:left;"
                        class="btn btn-info btn-sm"&gt;
                    &lt;i class="glyphicon glyphicon-search"&gt;&lt;/i&gt;
                &lt;/button&gt;


&lt;form method="post" name="changeItem" id="changeItem"&gt;
                    &lt;input type="text" name="changeItem" value="" id="changeItem" placeholder=""/&gt;
                &lt;/form&gt;

&lt;button type="submit" id="submit" form="changeItem" style="padding: 0 3px; float:left;"
                        class="btn btn-info btn-sm"&gt;
                    &lt;i class="glyphicon glyphicon-search"&gt;&lt;/i&gt;
                &lt;/button&gt;
</code></pre>

<p><strong>The problem you asked about:</strong></p>

<p>With</p>

<pre><code>if request.form['changeLocation'] != '':
</code></pre>

<p>you are probably trying to find out if that specific form was used. The problem is: when the correct form was used this check works but if a different form was used the <code>request.form</code> dictionary throws a key error. But it is not a normal <code>KeyError</code>. Flask will translate that "special" error to a <code>400 Bad Request</code>.</p>

<p>To check if a certain key is present in the form data use the <code>in</code> operator</p>

<pre><code>if "changeLocation" in request.form:
    # you can use request.form["changeLocation"] here
elif "changeType" in request.form:
    # here request.form["changeType"] is present
...
</code></pre>

<p><strong>Another problem:</strong></p>

<p>This line</p>

<pre><code>render_template('all-classifieds.html',location=location,transType=transType, data=data)
</code></pre>

<p>won't work, because <code>location</code> and <code>transType</code> are defined in the <code>if</code> blocks. It will fail if the blocks are not executed.</p>

<p><strong>Something different:</strong></p>

<pre><code>else:
    if condition:
         do_something
</code></pre>

<p>can be rewritten as</p>

<pre><code>elif condition:
    do_something
</code></pre>

python html forms flask http-status-code-400