I am new to programming and have only used a little bit of Python in the past. I am using Flask to build a website to host a scientific experiment. I am doing this on pythonanywhere.com. For the last part of the experiment, participants are shown 30 individual images and they have to say if they remember seeing the image in an earlier part of the experiment.
To do this I have created a javascript function that randomly shows one of 30 images every time changeImage() is run. Below it are two buttons saying "yes" and "no". Pressing the button should change the shown image and send "yes" or "no" to the flask_app.py, along with the variable "x" from javascript. This is so the Python function can save the number of the image and what answer the participant gives.
Javascript
var array2 = new Array();
var index = 0
var x = 0
for (var i = 1; i < 31; i++) {
array2.push(i);
}
function changeImage() {
if (array2.length) {
var index = Math.floor(Math.random() * array2.length);
x = array2[index];
var image = "/static/images/image" + x + ".jpg"
document.getElementById('ad').src = image;
array2.splice(index, 1);
}
}
HTML
<body onload="changeImage()">
<div class="w3-row-padding w3-padding-16 w3-center">
<img id="ad" class="img-fluid" src="/static/images/image99.jpg" />
<form action="{{ url_for('recog1') }}" id="answer" method="POST">
<div class="w3-center">
<input type="submit" id="answerY" value="Yes" name="Yes"
style="width:47%;" class="w3-bar-item w3-button w3-padding-medium w3-blue"
onclick= "changeImage();">
<input type="submit" id="answerN" value="No" name="No"
style="width:47%;" class="w3-bar-item w3-button w3-padding-medium w3-blue"
onclick= "changeImage();">
</div>
</form>
</body>
The problem is that I can't get my Python function to take the value of the buttons themselves. I do succesfully save data in an earlier part of the site where users have to enter their age and gender in a form, but I just can't get it to work when there are no fields to enter the data. The value from the button itself should be saved.
Python function
@app.route("/recog1", methods=["POST", "GET"])
def recog1():
if request.method == "GET":
return render_template("recog1.html")
Yes = request.form['Yes']
No = request.form['No']
entry_time = datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
#save to file
with open(BASE_DIR + '/userinfo/userinfo.csv', 'a+') as myfile:
myfile.write(
str(entry_time) + ', ' +
str(Yes) + ', ' +
str(No) + ', '
+ '\n')
myfile.close()
return redirect(url_for("thankyou"))
Now, there is a lot wrong with what is done with the data here and it would immediately go to the thankyou page, instead of waiting for thirty button clicks. I'll change those things later but first the problem is that I can't even get the button values to my python here. I always get "Bad Request: The browser (or proxy) sent a request that this server could not understand". I have looked at stackoverflow questions similar to this but they have never been useful to me or more likely, I didn't know how exactly to apply them to my case. Any amount of help would be greatly appreciated and thank you for taking the time to read!
EDIT: To solve the issue, the Yes = request.form['Yes']
and No = request.form['No']
in my python function needed to be replaced with x = request.form['Answer']
, where I set "Answer" as the name for both the buttons in HTML.
Try this in your python route
if request.method == 'POST':
if "answerY" in request.form:
print('yes button pressed')
elif "answerN" in request.form:
print('no button pressed')
edit1:
Try making a route like this, and then in your javascript function you could reroute to this route or handle it in your form action.
@app.route('/buttonresult/<button_id>', methods=['GET','POST'])
def buttonresult(button_id):
yes_string = ''
no_string = ''
if button_id == 'answerY':
# do something
yes_string = 'Yes'
elif button_id == 'answerN':
# do something
no_string = 'No'
entry_time = datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
#save to file
with open(BASE_DIR + '/userinfo/userinfo.csv', 'a+') as myfile:
myfile.write(
str(entry_time) + ', ' +
str(Yes) + ', ' +
str(No) + ', '
+ '\n')
myfile.close()
return redirect(url_for("thankyou"))
In order to redirect page from javascript function you can do this
# get button_id value somehow
windows.location.href = '/buttonresult/" + button_id
I think maybe I wasn't being very clear in my comment, so I'm posting this answer.
Try changing your recog1
function to the following:
@app.route("/recog1", methods=["POST"])
def recog1():
print(request.form)
return str(request.form)
When you press either the Yes
or No
button, what gets printed in your terminal/what do you see in the browser? Do you still receive the same error?
EDIT - When you press one of the two buttons, only one of the values will show up in request.form
. This makes sense if you think about it - you can only ever press one of the two buttons, but not both. If you press the "Yes" button, request.form
will have a key-value pair for Yes
, but not for No
. If you press the "No" button, request.form
will have a key-value pair for No
, but not for Yes
. The way your code is written right now, it assumes request.form
will always have both key-value pairs. This, of course, can never be true, and so regardless of what button you press, the missing key for the other one results in the error you're seeing.
You need to check for the presence of the Yes
and No
keys seperately, and then perform an action based on that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.