Как запросить форму, которая была создана списком из внешнего файла на python и HTML? Вызывает werkzeug.исключения.Ошибка BadRequestKeyError

#python #html #forms #for-loop #python-requests

Вопрос:

Я пытаюсь создать веб-сайт, который получает ответы пользователей в виде переключателей. Я сделал переключатели с циклом for и подумал, что мой код на python тоже сможет получать ответы пользователей с циклом for! Я очень новичок в этом, так что, скорее всего, я сделал что-то маленькое не так.

Я думаю, это может быть потому, что внутри цикла for я поместил request.form[word] и, возможно, запрос.форма не получает параметры, которые я ввел в функцию вычисления? Кроме того, я уже пробовал это, и, похоже, это не имеет никакого значения.

Я включил соответствующие части своего кода на python, файл txt, файл html для тестовой страницы и ошибку, которая отображается на моем экране.

Фрагмент кода Python

 # imports flask, a function which can redirect the current url # to a different one, and url_for from flask import Flask, redirect, url_for, render_template, request, session, flash import copy  # creating the app app = Flask(__name__) app.secret_key = "aC@nth8scdjkfdhfjdsfkdksm12345678910helloworlddlrowolleh"   # when you click on the link, it directs to this page @app.route("/") def home():  return render_template("index.html")   @app.route("/home") def tohome():  return redirect(url_for("home"))   # makes a list of the questions firstpage_questions = list() with open("firstquestions.txt", "r") as file:  for i in file:  firstpage_questions.append(i.rstrip("n"))  # this deep copy is so if I make any changes to the duplicated list it won't affect the original list. firstquestions = copy.deepcopy(firstpage_questions)  questlist = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)   # the request method means that if the sight reloads, the user still has their results saved @app.route("/takethetest", methods=["POST", "GET"]) def takethetest():  return render_template("takethetest.html", q=firstquestions, answers=questlist)   def calculate(firstq, lastq):  for word in firstquestions:  for num in questlist:  answered = request.form['question '   str(questlist[num-1])]  mental_issue = 0  if firstquestions.index(word) gt;= firstq and firstquestions.index(word) lt;= lastq:  if firstquestions.index(word) % 2 != 0:  mental_issue  = int(answered) * 10  elif firstquestions.index(word) % 2 == 0:  mental_issue  = (10 - int(answered)) * 10  else:  continue  else:  break  # make this an error handling thingy which posts it onto the website.  return mental_issue   @app.route("/results", methods=["POST"]) def results():  if request.method == "POST":  burn_out = calculate(1, 5)  stress = calculate(6, 10)  anxiety = calculate(11, 15)  return render_template("results.html", b=burn_out, s=stress, a=anxiety)  else:  return render_template("results.html")    # runs the app, and debug=true means that it reloads the page without # having to load it on this virtual environment   if __name__ == "__main__":  app.run(debug=True)  

Фрагмент файла Txt

 Over the past month, have you been procrastinating more than ever? 1 for nope, 10 for yes too much! In the last month, how often have you sat down and properly relaxed? Choose 1 for once, and 10 for I relax all the time. Have you eaten more/less in the past month? From one to ten how much have your eating habits changed? Do you have perfectionistic tendencies? If yes, pick 1. If you don't care at all that something is screwed up, pick 10. In the past ten days, how many days have you been completely exhausted and lost all motivation? How many days in the past ten days have you been having no problem falling asleep, or waking up completely refreshed? On a scale of one to ten how much do you worry or are nervous about an upcoming social situation? How many days in the past two weeks have you NOT noticed your heart racing randomly? 1 for heart racing all the time, 10 for not noticing. How many times a day do you get easily irritated by other people/things? From 1 to 10. Do you ever feel ‘on edge’ or unsettled? 1 for all the time, 10 for no. How many times have you felt like you’ve been on ‘low power mode’ in the last two weeks? 1 for 1 day or less, 10 for 10 days or more. How many days in the past two weeks has your skin been normal (no extra pimples, sores etc.)? 1 for my skin has been so bad, to 10 for perfect skin. Have you ever caught yourself clenching your jaw or grinding your teeth in the past month? 1 for never, and 10 for all the time. In the past month, have you had a normal digestive routine, with no irregularities such as diarrhoea and constipation? 1 for never, and 10 for nothing wrong with my bowels. Have you bitten your nails, fidgeted with your phone, or showed any nervous behaviours more frequently in the past two weeks? 1 for 1 day or less, 10 for 10 days or more.  

HTML Take The Test File

 {%extends "base.html" %} {% block title %}Take the Test{% endblock %} {% block content %} lt;headgt;  lt;link href="https://stackpath.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet"gt; lt;/headgt; lt;bodygt; lt;div class="container-fluid"gt;  lt;div class="row vh-100"gt;  lt;div class="col-1"gt;lt;/divgt;  lt;div class="col-6"gt;  lt;h3gt;About The Testlt;/h3gt;  lt;p class="blue"gt;This test will ask you if you seem to have any of the different symptoms of burn out, anxiety and extreme  stress. Consider these questions as abnormal things you usually don’t do – like if you usually  procrastinate and know it’s part of your personality, think if you have procrastinated more than usual.  This test has been designed for teenagers, but is suitable for all ages. lt;/pgt;  lt;/divgt;  lt;div class="col-1"gt;lt;/divgt;  lt;div class="col-3"gt;  lt;i class="glyphicon glyphicon-star" aria-hidden="true"gt;lt;/igt;lt;p class="blue"gt;Test questionslt;/pgt;  lt;i class="glyphicon glyphicon-star-empty" aria-hidden="true"gt;lt;/igt;lt;p class="blue"gt;More test questionslt;/pgt;  lt;i class="glyphicon glyphicon-star-empty" aria-hidden="true"gt;lt;/igt;lt;p class="blue"gt;Your Resultslt;/pgt;  lt;/divgt;  lt;div class="col-1"gt;lt;/divgt;  lt;/divgt;  lt;div class="row vh-500"gt;  lt;div class="col-2"gt;lt;/divgt;  lt;div class="col-8"gt;  lt;form action='/secondtestpage' method='POST'gt;  lt;olgt;  {% for qnum,qtext in enumerate(q) %}  lt;ligt;{{qtext}}lt;/ligt;  lt;labelgt;{% for anum,atext in enumerate(answers) %}  {{atext}} lt;input type='radio' value='{{anum}}' name="question{{qnum}}"/gt;  {% endfor %}lt;/labelgt;  {% endfor %}  lt;input type="submit" value=" Next Page "/gt;  lt;/olgt;  lt;/formgt;  lt;/divgt;  lt;div class="col-2"gt;lt;/divgt;  lt;/divgt; lt;/divgt; lt;/bodygt; {% endblock %}  

Ошибка, Которая Возникает

 burn_out = calculate(firstquestions, 1, 5) File "/Users/arimulligan/PycharmProjects/pythonProject1/hello.py", line 47, in calculate  return render_template("takethetest.html", q=firstquestions, answers=questlist)     def calculate(first_list, firstq, lastq):  for word in first_list:  answered = request.form[word]  mental_issue = 0  if first_list.index(word) gt;= firstq and first_list.index(word) lt;= lastq:  if first_list.index(word) % 2 != 0:  mental_issue  = int(answered) * 10  elif first_list.index(word) % 2 == 0: File "/Users/arimulligan/PycharmProjects/pythonProject1/venv/lib/python3.9/site-packages/werkzeug/datastructures.py", line 377, in __getitem__ raise exceptions.BadRequestKeyError(key) werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'Over the past month, have you been procrastinating more than ever? 1 for nope, 10 for yes too much!'  

Если вы хотите узнать что-нибудь еще об этом, не стесняйтесь спрашивать! И заранее извиняюсь, если мой код неаккуратен.

Комментарии:

1. Вы не показали нам ни одного кода на Python. На самом деле не очень разумно задавать имя lt;inputgt; тега для всего вопроса, потому что это имя будет использоваться для переменной в ответе. Вы должны использовать такие имена , как question1 , или что-то, что можно использовать в качестве имени переменной.

2. @TimRoberts Я только что понял и вставил весь свой код прямо сейчас 🙂 Теперь я использовал имя входного тега как 'question {{answers[number-1]}}' и обновил код, чтобы соответствовать этому, спасибо. Тем не менее, он все равно выдает ту же ошибку

3. Но вы также должны указать там номер вопроса. Вы смотрели на HTML, который вы генерируете? Вам нужно это сделать, потому что это не то, что вы думаете. Элементы вашей радиоприемной коробки должны иметь такие имена , как question-1-3 , что является ответом № 3 на вопрос № 1. И помните, когда вы это сделаете for number in answers , number это будет ОТВЕТ, а не индекс ответа, о котором вы, кажется, думаете. Возможно, вам потребуется использовать for qnum,question in enumerate(q) и. for anum,answer in enumerate(answers)

Ответ №1:

Это должно генерировать полезный HTML-код. Затем вы secondtestpage получите элементы, например question0 , со значением 1 для ответа № 1 на вопрос № 0. Добавьте 1 к ним, если хотите.

 lt;form action='/secondtestpage' method='POST'gt;  lt;olgt;  {% for qnum,qtext in enumerate(q) %}  lt;ligt;{{qtext}}lt;/ligt;  lt;labelgt;{% for anum,atext in enumerate(answers) %}  {{atext}} lt;input type='radio' value='{{anum}}' name="question{{qnum}}"/gt;  {% endfor %}lt;/labelgt;  {% endfor %}  lt;input type="submit" value=" Next Page "/gt;  lt;/olgt;  lt;/formgt;  

Комментарии:

1. Большое вам спасибо! В этом больше смысла 🙂 Но всякий раз, когда я запускаю код, он все равно выдает эту ошибку: line 85, in results burn_out = calculate(0, 4) line 52, in calculate: answered = request.form['question' str(qnum)] in __getitem__ raise exceptions.BadRequestKeyError(key) werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'question0' это может быть из-за моего кода на python? Как бы я это изменил?

2. Это говорит о том, что он не нашел question0 . Вы заполнили все вопросы? Вы можете использовать if 'question' str(qnum) not in request.form: его, чтобы проверить, есть ли он там.

3. Я все понял! Я использовал метод POST на другую html-страницу, не связывая файл take the test! Вот почему он не смог найти question0, потому что на другой html-странице не было question0 в форме. Спасибо вам за вашу помощь 🙂