Flask wtforms - 'UnboundField' object is not callable, dynamic field won't init properly
Asked Answered
O

1

6

app.py

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FieldList, FormField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'apple pie'


class BookForm(FlaskForm):
    book = StringField('book title')


class LibraryForm(FlaskForm):
    def __init__(self, min_entries=0, *args, **kwargs):
        super(LibraryForm, self).__init__(*args, **kwargs)
        self.books = FieldList(FormField(BookForm), min_entries=min_entries)

    library = StringField('Library name')
    books = FieldList(FormField(BookForm), min_entries=3)
    submit = SubmitField('Submit')


@app.route('/book', methods=['GET', 'POST'])
def book():
    form = LibraryForm(min_entries=5)
    if form.validate_on_submit():
        return 'aww yeah'
    return render_template('books.html', form=form)

books.html

<html>
<form method="POST" action="">
    {{ form.hidden_tag() }}
    <div>{{ form.library.label }}: {{ form.library() }}</div>
    <div>{{ form.books.label }}: {{ form.books() }}</div>
    <div>{{ form.submit.label }}: {{ form.submit() }}</div>
</html>

My goal is to make my form init with a flexible number of entries, such as in the example shown in the link. Whenever I run my code I get the following error:

TypeError: 'UnboundField' object is not callable

When I comment out the init function, the form works as expected, apart from the non-flexible amount of Book Fields. I've spent quite some time looking for answers, but couldn't find any which solved the problem.

example of how it should look

Any help is appeciated!

Outgoings answered 9/2, 2018 at 0:36 Comment(0)
O
3

It's not the ideal solution, but this works though.

from flask import Flask, render_template
from flask_wtf import FlaskForm, Form
from wtforms import StringField, SubmitField, FieldList, FormField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'apple pie'


class BookForm(FlaskForm):
    book = StringField('book title')


class LibraryForm(FlaskForm):
    library = StringField('Library name')
    books = FieldList(FormField(BookForm))
    submit = SubmitField('Submit')


@app.route('/book', methods=['GET', 'POST'])
def book():
    form = LibraryForm()
    if form.validate_on_submit():
        return 'aww yeah'
    for i in range(6):
        form.books.append_entry()

    return render_template('books.html', form = form)
Outgoings answered 9/2, 2018 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.