I can't work out why Wtforms is not preventing submission of the form when an error is detected. Instead of displaying the error message it submits the form and then I get a "TypeError: The view function did not return a valid response" because my "routes" code only has a return statement at the end of the validate_on_submit block. This means that the form is correctly detecting the validation error - but why is the form being submitted? Shouldn't this be prevented because of the validation error?
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, FloatField, SelectField, HiddenField, Form, FormField, FieldList
from wtforms.validators import DataRequired, Optional, InputRequired, ValidationError
class Vent_form(FlaskForm):
hidden_id = HiddenField('Vent id')
room_height = FloatField('Room height (m)',validators=[DataRequired()])
air_change = FloatField('Air tightness @50Pa',validators=[DataRequired()])
vent_type = SelectField('Ventilation type', validators=[DataRequired()], choices=['Natural','Extract only','Balanced'])
mvhr = SelectField('MVHR unit', validators=[DataRequired()], choices=['None','Default'])
vent_rate = FloatField('Purpose vent rate',validators=[DataRequired()])
submit = SubmitField('Submit data')
routes.py
@app.route('/Ventilation', methods = ['GET', 'POST'])
def Vent_disp():
if 'project_name' not in session:
session['project_name'] = "0: No project selected"
project_name = session['project_name'].split(':')[1]
project_choices = [(str(c.id) + ': ' + c.project_name) for c in Peter.query.all()]
form2 = Which_project(project_choice = session['project_name'])
form2.project_choice.choices = project_choices
form_edit = Vent_form()
if form2.submit.data:
session['project_name'] = form2.project_choice.data
project_name = session['project_name'].split(':')[1]
return render_template('Ventilation.html', form_edit=form_edit, form2=form2, ventilation = Ventilation.query.filter_by(project_id=session['project_name'].split(':')[0]).all(), project_name=project_name)
@app.route('/Edit_vent', methods = ['GET', 'POST'])
def Edit_vent():
form_edit = Vent_form()
if form_edit.validate_on_submit():
ventilation = Ventilation.query.get(form_edit.hidden_id.data)
ventilation.room_height = form_edit.room_height.data
ventilation.air_change = form_edit.air_change.data
ventilation.vent_type = form_edit.vent_type.data
ventilation.mvhr = form_edit.mvhr.data
ventilation.vent_rate = form_edit.vent_rate.data
db.session.commit()
return redirect(url_for('Vent_disp'))
html:
<div class="modal-body">
<form action = "{{ url_for('Edit_vent') }}" method = "post" novalidate>
<div class="container-fluid">
{{ form_edit.csrf_token }}
{{ form_edit.hidden_id(value=row.id) }}
<p>{{ form_edit.submit() }}</p>
<div class="row">
<div class="form-group col-sm-6">
{{ form_edit.room_height.label }}
{{ form_edit.room_height(class="form-control", value=row.room_height) }}
{% for error in form_edit.room_height.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
etc