Проблема с колбой с кнопкой включения/выключения

#python #flask #button

Вопрос:

Я разрабатываю веб-интерфейс с flask, в котором пользователь может вводить значения в форму, а затем отправлять значение через http-сервер. После этого я собираю значения и отправляю их на сервер OPC-UA, подключенный к двигателю, который должен вращаться.

Я хочу заполнить форму, а затем сохранить значения, нажав кнопку Отправить. Но я также хочу создать еще одну кнопку, которая при нажатии на нее автоматически заполняет форму значениями по умолчанию (в моем случае я хочу, чтобы везде было 0). Эта вторая кнопка-кнопка «ВКЛ./ВЫКЛ.». В начале кнопка «Выключена», что означает, что мы должны отправить значение 0 (двигатель не вращается, когда мы отправляем угол=0, скорость=0…). Затем, когда он будет включен, я смогу отправлять значения.

Кнопка Отправить работает хорошо и правильно отправляет выбранное значение от пользователя.

Однако я не знаю, почему другая кнопка не работает. Всякий раз, когда я нажимаю на него, ничего не происходит, никакого сообщения об ошибке.

Вот мой код:

 # sends data from html form to database
from flask import Flask 
from flask import request 
from flask import render_template

app = Flask(__name__)
@app.route('/')
def form():
    return render_template('form.html',drive_state='Off') 


function_id = 0
angle = 0
speed = 0

@app.route('/', methods=['POST'])
def get_parameters():
    if request.form.get("submit"):
        function_id = request.form['function_id']
        angle = request.form['angle']
        speed = request.form['speed']  
        opc_state = 1
        print(function_id)
        print(angle)
        print(speed)
        # drive_state=request.form['drive_state'] 
    if request.form.get("turn_on"):
        function_id = 0
        angle = 0
        speed = 0
        # call opcua func    
        # opcua_state = opc_read
        opc_state = 0
        if opc_state == 0:
            drive_state = 'Off'
            opc_state = 1
        if opc_state == 1:
            drive_state = 'On'
            opc_state = 0

    # return redirect(request.url)
    return render_template('form.html', function_id=function_id, angle=angle, speed=speed)
# get_parameters()
# print(form_params)
 

 <!DOCTYPE HTML>
<html>
<head>
    <title>Sample page to test fill_web_form.py</title>
</head>
<body>
    <p1><strong>SAMPLE PAGE TO TEST FILL_WEB_FORM.PY</strong></p1>

    <!--test form-->
    <form method="post" action="/">
        Test the motor:<br>
        <table> 
            <tr> 
                <td> Function number: </td> 
                <td> <input type="text" name="function_id" value={{function_id}}> </td> 
            </tr> 
            <tr> 
                <td> Angle: </td> 
                <td> <input type="text" name="angle" value={{angle}}> </td> 
            </tr> 
            <tr> 
                <td> Speed: </td> 
                <td> <input type="text" name="speed" value={{speed}}> </td> 
            </tr> 
            <tr> 
                <td> <input type="submit" name="submit" Value="Submit"> </td> 
            </tr> 
            <tr> 
                <td> <input type="button" name="drive_state" Value={{drive_state}}> </td> 
            </tr>
        </table>
    </form>
</body>
</html>
 

Пользовательский интерфейс выглядит следующим образом:

введите описание изображения здесь

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

1. Я не уверен, хорошо ли я понял, но я думаю, что для вас проще выполнить некоторые функции javascript с помощью кнопки «Выкл.», и как только вы нажмете ее, она заполнит все поле значением по умолчанию «0», а затем вы сохраните его. В противном случае я советую вам иметь 2 разные конечные точки и использовать для кнопки выключения API GET.

2. да, но я должен закодировать его на python…

3. поэтому создайте еще одну кнопку включения (GET) API, которая вернет вам значение по умолчанию, и с ее помощью вы заполните пользовательский интерфейс; это всего лишь вторая конечная точка в том же приложении Flask

4. создайте два <form> — первый со всеми input и submit и второй только с OFF

5. ваша вторая кнопка не работает, потому что у нее есть имя name="drive_state" , но вы проверяете имя if request.form.get("turn_on"): . Вы просто используете два разных имени. Вы должны проверить if request.form.get("drive_state"): , но вы должны поместить эту кнопку отдельно <form> , чтобы отправлять это значение только при нажатии на нее.

Ответ №1:

Я вижу мало проблем.

Первый. У второй кнопки есть имя name="drive_state" , но вы проверяете имя

 if request.form.get("turn_on"):
 

Вы должны проверить

 if request.form.get("drive_state"):
 

Но это должно быть type="submit" для отправки на сервер.

  <input type="submit" name="drive_state" Value={{drive_state}}> 
 

Другой проблемой являются локальные переменные в функции, которые удаляются между запросами. Вы должны использовать global функцию информирования о том, что она должна хранить ее в глобальных переменных, чтобы они не были удалены.


Еще одна проблема. Если ты побежишь

     if opc_state == 0:
        #... code ...
        opc_state = 1

    if opc_state == 1:
        # ... code ...
        opc_state = 0
 

затем if будет установлен первый, opc_state = 1 но затем он запустится вторым if , который вернет его обратно opc_state = 0 . Вы должны использовать elif , иначе

     if opc_state == 0:
        #... code ...
        opc_state = 1

    #elif opc_state == 1:
    else:
        # ... code ...
        opc_state = 0
 

И вы забыли отправить drive_state в шаблон


Минимальный рабочий код с HTML непосредственно в коде, чтобы каждый мог просто скопировать его и запустить.

 html = '''<!DOCTYPE HTML>
<html>
<head>
    <title>Sample page to test fill_web_form.py</title>
</head>
<body>
    <p1><strong>SAMPLE PAGE TO TEST FILL_WEB_FORM.PY</strong></p1>

    <!--test form-->
    <form method="post" action="/">
        Test the motor:<br>
        <table> 
            <tr> 
                <td> Function number: </td> 
                <td> <input type="text" name="function_id" value={{function_id}}> </td> 
            </tr> 
            <tr> 
                <td> Angle: </td> 
                <td> <input type="text" name="angle" value={{angle}}> </td> 
            </tr> 
            <tr> 
                <td> Speed: </td> 
                <td> <input type="text" name="speed" value={{speed}}> </td> 
            </tr> 
            <tr> 
                <td> <input type="submit" name="submit" Value="Submit"> </td> 
            </tr> 
            <tr> 
                <td> <input type="submit" name="drive_state" Value={{drive_state}}> </td> 
            </tr>
        </table>
    </form>
</body>
</html>'''

# sends data from html form to database
from flask import Flask 
from flask import request 
from flask import render_template_string

app = Flask(__name__)
@app.route('/')
def form():
    return render_template_string(html, drive_state='Off') 

function_id = 0
angle = 0
speed = 0
drive_state = 'Off'
opc_state = 0

@app.route('/', methods=['POST'])
def get_parameters():
    global function_id
    global angle
    global speed
    global drive_state
    global opc_state
    
    if request.form.get("submit"):
        function_id = request.form['function_id']
        angle = request.form['angle']
        speed = request.form['speed']  
        opc_state = 1
        print('function_id:', function_id)
        print('angle:', angle)
        print('speed:', speed)

    if request.form.get("drive_state"):
        function_id = 0
        angle = 0
        speed = 0
        # call opcua func    
        # opcua_state = opc_read
        #opc_state = 0
        
        if opc_state == 0:
            drive_state = 'Off'
            opc_state = 1
        elif opc_state == 1:  # it has to be `else`
            drive_state = 'On'
            opc_state = 0
        print('drive_state:', drive_state)

    # return redirect(request.url)
    return render_template_string(html, function_id=function_id, angle=angle, speed=speed, drive_state=drive_state)

app.run()