Выпадающий список HTML не возвращает модуль Python в маршруте Flask

#html #python-3.x #pandas #flask

#HTML #python-3.x #pandas #flask

Вопрос:

У меня есть два сценария, которые заканчиваются фреймами данных, загруженными в мой app.py . Выпадающие списки на моей первой странице HTML — это имена столбцов обоих фреймов данных. При нажатии кнопки отправки я пытаюсь перенаправить выбранные элементы в третий модуль regrplot app.py . Этот модуль будет использовать выделение для определения фреймов данных, объединения двух в столбце year и запуска генератора изображений графика регрессии.

Ошибка, которую я получаю: UnboundLocalError: local variable 'y1' referenced before assignment

При переходе на dropdown.html страницу. Я могу видеть заполненные выпадающие списки, а также кнопку отправки.

Переменные с df их именем — это фреймы данных, импортированные из других модулей.

 dropdown.html

  <body>
    <form name="var1" action="/dropdown_x">
       <fieldset>
          <legend>Table Variable 1</legend>
          <p>
             <label>Select</label>
             <select name="df_variable1">
                {% for each in dropdown_fields %}
                  <option value="{{each}}">{{each}}</option>
                {% endfor %}
                </select>
          </p>
       </fieldset>
    </form>
    <form name = "var2" action="/dropdown_y">
        <fieldset>
           <legend>Table Variable 2</legend>
           <p>
              <label>Select</label>
              <select name="df_variable2">
                 {% for each in dropdown_fields %}
                   <option value="{{each}}">{{each}}</option>
                 {% endfor %}
                 </select>
           </p>
        </fieldset>
        <button><input name="regrplt" method="GET" action="/regrplot" type="submit" class="btn btn-default"  value="Submit"></button>     
     </form>

  </body>

 
 app.py

import pandas as pd

app = Flask(__name__)

book_fields= list(book_data.year_book_data)
census1_fields = list(censusLoad.df_full1)
census2_fields = list(censusLoad.df_full2)
dropdown_fields = book_fields   census1_fields   census2_fields



@app.route("/dropdown")
def dropdownList():
    return render_template('dropdown.html', dropdown_fields=dropdown_fields)


@app.route("/dropdown_x", methods=['GET', 'POST'])
def testt1():
    if request.method == 'POST':
        df_variable1 = request.form['df_variable1']

        if df_variable1 in book_fields:
           x1 = book_data.df_yearbook
        if df_variable1 in census1_fields:
           x1 = censusLoad.df_full1
        if df_variable1 in census2_fields:
           x1 = censusLoad.df_full2


    return x1

@app.route("/dropdown_y", methods=['GET', 'POST'])
def testt2():
    if request.method == 'POST':

        df_variable2 = request.form['df_variable2']

        if df_variable2 in book_fields:
           y1 = book_data.df_year_book
        if df_variable2 in census1_fields:
           y1 = censusLoad.df_full1
        if df_variable2 in census2_fields:
           y1 = censusLoad.df_full2

    return y1




@app.route("/regrplot", methods=['GET','POST'])
def regrplot():
    if request.method == 'POST':

# Have tried with and without this block
        df_variable1 = request.form['df_variable1']
        df_variable2 = request.form['df_variable2']

        if df_variable1 in book_fields:
            x1 = book_data.df_yearbook
        if df_variable1 in census1_fields:
            x1 = censusLoad.df_full1
        if df_variable1 in census2_fields:
            x1 = censusLoad.df_full2

        if df_variable2 in book_fields:
            y1 = book_data.df_yearbook
        if df_variable2 in census1_fields:
            y1 = censusLoad.df_full1
        if df_variable2 in census2_fields:
            y1 = censusLoad.df_full2
#

        Reg_df = x1.merge(y1, how = "inner", left_on ='year', right_on = 'year')
        plot = sns.regplot(x=f'{df_variable1}', y=f'{df_variable2}', data = Reg_df)
        plot.savefig('regrplot', format='png')

    return render_template("regression.html")

if __name__ == "__main__":
    app.run(debug=True)
 
 regression.html

<!DOCTYPE HTML>
<html lang = "en">
  <head>
    <title>formDemo.html</title>
    <meta charset = "UTF-8" />
  </head>
  <body>
      <image src="regrplot.png"></image>
    </body>
</html>
 

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

1. Какой смысл иметь /dropdown_x /dropdown_y конечные точки and? Они на самом деле не нужны /regrplot ?

2. Новичок в flask so, я не уверен, правильно ли я использую декоратор здесь. Однако функции, определяющие dropdown_(x,y) маршруты, предназначены для возврата dfs for .merge() метода pandas in /regrplot . Данные df_variables из выбранной формы также предназначены для предоставления переменных для .regplot() in plot . В строке с комментариями показано, где я пытался использовать его в .regplot() функции и из нее.

Ответ №1:

Я не тестировал, но попробуйте эти исправления:

Вариант 1. Для использования метода «request.form» для форм необходимо установить значение POST, в противном случае вместо этого используйте метод «request.args» (GET). Вот почему я считаю, что у вас ошибка, когда «y1» не определено, потому что условие «request.method == ‘POST'» равно False, поэтому «y1» никогда не объявлялся. Должно быть то же самое для «x1».

 <form name="var1" action="/dropdown_x" method="post">
 

Вариант 2: если вы используете GET, попробуйте проверить «GET» вместо «POST»:

 if request.method == 'GET':
  df_variable1 = request.args['df_variable1']
 

Убедитесь, что вы используете «request.args.get(‘df_variable1’) или «request.args [‘df_variable1’]», потому что «request.form []» работает только для «POST».

Для лучшей практики вы должны объявить «x1» и «y1» в случае, если условие ложно, и в этом случае «x1» и «y1» будут неопределенными.

Надеюсь, это сработает.

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

1. Спасибо. Похоже regrplot , функция запущена, но при возврате я получаю сообщение об ошибке. TypeError: 'DataFrame' object is not callable The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a DataFrame. Собираюсь поиграть с возвратом и посмотреть, смогу ли я это исправить