2

I'm trying to read a form using Flask, WTForms and the macros that are made available via flask-Bootstrap. This works in some cases and in other - seemingly similar ones - it doesn't. When I check the content of a specific StringField it always evaluates to None, failing the InputRequired() validation.

forms.py:

from wtforms import Form, validators, \
                    StringField, PasswordField, SubmitField, \
                    SelectField, RadioField
from wtforms.fields.html5 import DateField
from wtforms.validators import ValidationError, InputRequired, NoneOf, \
                               EqualTo, Length, Optional

class TestForm(Form):
    name = StringField('Name', [validators.InputRequired(message='Please enter name!')])
    date = DateField('Date', format='%Y-%m-%d') #, default=date.today())
    address = StringField('Address')
    submit = SubmitField('Add')

test.py:

from flask import render_template, redirect, request
from flask_security import login_required
from application.routes import routes
from application.forms import TestForm

@routes.route('/test', methods=['POST', 'GET'])
@login_required
def test():
    form = TestForm()
    print(form.name.data)
    if request.method == 'POST' and form.validate():
        print("validated")
        return redirect("/")
    return render_template('test.html', title="Asset Manager", form=form)

test.html:

{% extends 'layout.html' %}

{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
  <div class="container-fluid">
    <h3><u>Test:</u></h3>
    <br>
    <div class="container-fluid col-md-3">
      <form action="" method="POST" class="form" role="form" onsubmit="/">
        <div class="row">
          <div class="col-md-12">
            {{ wtf.form_field(form.name, form_type="inline", placeholder="Name") }}
          </div>
        </div>
        <div class="row">
          <div class="col-md-5">
            {{ wtf.form_field(form.date) }}
          </div>
        </div>
        <div class="row">
          <div class="col-md-12">
            {{ wtf.form_field(form.address) }}
          </div>
        </div>
        {{ wtf.form_field(form.submit, class="btn btn-primary") }}
      </form>
      {% for message in get_flashed_messages() %}
      <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
      </div>
    </div>
    {% endfor %}
  </div>
{% endblock %}

This always puts out None and consequently never gets past the validation check even when I enter a name and press the Add button. I tried creating a minimal example (which still exhibits the same problem), but I left out large parts of the application, so if you need more information - please let me know and I'll be happy to provide them.

Midnight
  • 373
  • 2
  • 11
  • 2
    A couple of things, TestFrom and AssetManagerForm are different things? Where are you using the incoming form to process anything since now it initializes a new Testform which you then try to validate? Try changing form.validate() to request.form.validate() – Marc Sep 24 '19 at 10:56
  • Yeah, I meant to replace AssetManager everywhere to make the whole example look more generic (edited it now). Your question pointed me in the right direction however. I forgot to add request.form in my form constructor. Using form = TestForm(request.form) worked out. – Midnight Sep 24 '19 at 11:24

1 Answers1

1

Thanks to Marc I found where I missed something. When instantiating the form I need to pass the request as an argument. So the line

form = TestForm()

needs to be changed to

form = TestForm(request.form)

To make the application work.

Midnight
  • 373
  • 2
  • 11