Веб-приложение: Flask - html - wtforms: форма с двумя кнопками отправки - PullRequest
1 голос
/ 06 августа 2020

Я новичок в программировании. Меня интересует разработка простого веб-приложения с двумя входными значениями и двумя кнопками отправки. Числа A и B вводятся пользователями, и в зависимости от того, какая кнопка нажата, будет отображаться произведение ИЛИ сумма. Когда я использую одну кнопку, код работает; однако я не могу понять, как заставить работать обе кнопки. Я написал приложение в Flask и Python 3.8 и использовал wtforms.

Вот мои коды: view. html



<table>
  {% for field in form %}
    <tr>
    <td>{{ field.name }}</td><td>{{ field }}</td>
    <td>{{ field.label }}</td>
    </tr>
  {% endfor %}
</table>

<form method="post" action="">
<input type="submit" name="btn" value="Add">
</form>
<p>
<form method="post" action="">
<input type="submit" name="btn" value="Multiply">
</form></p>

<p>
{% if result != None %}
{{result}}
{% endif %}
</p>

Python code views.py


@app.route("/comp", methods=['GET', 'POST'])
def comp():
    form = InputForm(request.form)
    if request.method == 'POST' and form.validate():
        if request.form["btn"] == "Add":
            result = add(form.A.data, form.B.data)
        
        elif request.form["btn"] == "Multiply":
            result = mul(form.A.data, form.B.data)
    else: result = None
    return render_template('view.html', form=form, result=result)

Я определил функции mul () и add () в отдельном файле, так как я планирую расширять приложение в будущем. Вот определение функции:


def mul(A,B):
    return  A*B
def add(A,B):
    return  A+B

Мой файл input.py:

from wtforms import Form, FloatField, validators

class InputForm(Form):
    A = FloatField(
        label='A', default=0,
        validators=[validators.InputRequired()])
    B = FloatField(
        label='B', default=0,
        validators=[validators.InputRequired()])

Ответы [ 4 ]

0 голосов
/ 06 августа 2020

Хорошо, я исправлю ваш код. Первым делом это результат:

Flask Код:

from flask import Flask, request, render_template, url_for, flash, redirect
from wtforms import SubmitField, Form, FloatField, validators


app = Flask(__name__)

app.config['SECRET_KEY'] = 'dev'

def mul(A,B):
    return  A*B
def add(A,B):
    return  A+B

# Form
class InputForm(Form):
    A = FloatField(
        label='A', default=0,
        validators=[validators.InputRequired()])
    B = FloatField(
        label='B', default=0,
        validators=[validators.InputRequired()])
   
       
       
@app.route('/comp', methods=['GET', 'POST'])
@app.route('/', methods=['GET', 'POST']) #this so that both url will work
def comp():

    result = ''   #already assign a variable, else will throw error
    form = InputForm(request.form)
    if request.method == 'POST': #First we check if method is post **POINT 2**
            if form.validate(): #Then if form is validate
                print('form ok') #Test if form is ok
                if request.form['btn'] == 'Add':
                    result = add(form.A.data, form.B.data)
                    print(result) 
            
                elif request.form['btn'] == 'Multiply':
                    result = mul(form.A.data, form.B.data)
                    print(result)
                
                flash(result) # **POINT 3**
                return redirect('comp') # This will make your code run forever #**4**     
            else:
                print('form no ok ') #check if form no ok
    else:
        print('request is get') # if you put the form.validate with the method condition, the form will return False as soons as you render the template

    return render_template('view.html', form=form, result=result)


if __name__ == '__main__':
    app.run(debug=True)

HTML файл:

  <form method="post" action="">
      <table>
        <!-- Generates form fields -->
        <!-- POINT 1 -->
        {% for field in form %}  

            <td>{{ field.name }}</td><td>{{ field }}</td>
            <td>{{ field.label }}</td>
          </tr>
          
        {% endfor %}
        
        <tr>
          <!-- Input are inside the form tag -->
          <td><input type="submit" name="btn" value="Add"></td>
          <td><input type="submit" name="btn" value="Multiply"></td>

        </tr>
      </table>
    </form>

<!-- Print result in the browser  -->
<!-- Needs to redirect to the same page -->
<!-- return redirect('comp')    -->

  {% for msg in get_flashed_messages()%}
  <h1>   {{msg}} </h1> 
  {% endfor%}
  1. Итак, основная проблема заключалась в том, что в HTML форма не вместе с полем ввода, поэтому форма разрабатывалась отдельно. Если сложить все вместе, он начнет работать.
В файле python условие if request.method == 'POST' выполняется одновременно с формой, следовательно, форма возвращается False даже перед ее отправкой.

.3 Добавлен метод Fla sh, чтобы вы могли видеть результат

.4 Добавьте перенаправление, это отобразит sh результат в браузере, но самое главное обновит sh форму и даст вам возможность добавить новую.

Обратите внимание, что также важно перенаправить страницу, потому что представьте, если вы хотите зафиксировать ее в базе данных, это сделает вы отправляете форму и сохраняете изменения.

0 голосов
/ 06 августа 2020

Если я понимаю проблему, попробуйте сделать это:

from flask import render_template, redirect, url_for, fla sh, request

@app.route('/comp') #sample only
def comp():

    form = InputForm(request.form)
    if request.method == 'POST' and form.validate()
        if request.form['btn'] == 'Add':
            result = add(form.A.data, form.B.data)

        elif request.form['btn'] == 'Multiply':
            result = mul(form.A.data, form.B.data)
        flash(result) # see the result in the browser
        print('result') # see the result in the terminal
        return redirect(url_for('comp'))
    else:
        result = None
    return render_template('view.html', form=form, result=result)

для реализации fla sh в html simple добавьте это где-нибудь

{% for msg in get_flashed_messages()%}
   <h1> {{msg}} </h1>
{% endfor %}

Я всегда добавляю инструкцию print и fla sh для устранения неполадок, чтобы увидеть, в чем проблема.

0 голосов
/ 06 августа 2020

У вас есть 3 разных формы. A и B не являются частью отправляемой вами формы.

0 голосов
/ 06 августа 2020

Одно из ваших значений - «ADD», но вы проверяете «Добавить». Итак, проверка на равенство не выполняется.

UPDATE:

Где вы определяете add() и mul()? Возможно, вместо этого используйте:

if request.form['btn'] == 'Add':
    result = form.A.data + form.B.data

elif request.form['btn'] == 'Multiply':
    result = form.A.data * form.B.data

UPDATE2:

Попробуйте это для диагностики:

if request.method == 'POST' and form.validate():
    print(request.form["btn"])
    print(form.A.data, form.B.data)
    print(request.POST)
...