user3344239 user3344239 - 2 months ago 10
HTML Question

python-flask html form help/suggestions

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 400 bad request error. Any suggestions or guidance as to why this is isn't working when I add in the forms for changing item and transaction type?

@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))


HTML:

<form method="post" id="changeLocation" name="changeLocation" action="">

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

</optgroup></select></form>


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




<form method="post" name="changeType" id="changeType">


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

</optgroup>
</select>



<form method="post" name="changeType" id="changeType">


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

</optgroup>
</select></form>

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


<form method="post" name="changeItem" id="changeItem">
<input type="text" name="changeItem" value="" id="changeItem" placeholder=""/>
</form>

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

Answer

The problem you asked about:

With

if request.form['changeLocation'] != '':

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 request.form dictionary throws a key error. But it is not a normal KeyError. Flask will translate that "special" error to a 400 Bad Request.

To check if a certain key is present in the form data use the in operator

if "changeLocation" in request.form:
    # you can use request.form["changeLocation"] here
elif "changeType" in request.form:
    # here request.form["changeType"] is present
...

Another problem:

This line

render_template('all-classifieds.html',location=location,transType=transType, data=data)

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

Something different:

else:
    if condition:
         do_something

can be rewritten as

elif condition:
    do_something