3

I have to make a lot of RadioFields, and I thought it would be good to dynamically generate them, but I can't get the code working. I'm using Flask and flask-wtf.

Form definition:

from flask_wtf import FlaskForm
from wtforms import RadioField, SubmitField

class GenerateForm(FlaskForm):
    def binary_generator(self, label_text, yes_text, no_text):
        return RadioField(label_text, choices=[(1, yes_text), (0, no_text)])

    submit = SubmitField('submit')

Flask app:

import GeneratorForm

form = GeneratorForm
form.radio_one = form.binary_generator('test label', 'yes', 'no')

render_template('file.html', form=form)

Jinja:

{{ form.radio_one.label }}
{{ form.radio_one(style="list-style: none") }}

The Jinja fails with: wtforms.fields.core.UnboundField object has no attribute label

So it looks like the class binary_generator function is working ok, but not constructing the form properly?

2 Answers 2

3

Do you need that binary_generator method in GenerateForm ?

Your GenerateForm could look something like this:

from flask_wtf import FlaskForm
from wtforms import RadioField, SubmitField

class GenerateForm(FlaskForm):
    radio_fields = RadioField('', choices=[])
    submit = SubmitField('submit')

And in your flask application, you need to instantiate your form like this:

import GeneratorForm

form = GeneratorForm() # Instantiate it

form.radio_fields.label = 'Label Example'
form.radio_fields.choices = [('value_1', 'description'), ('value_2', 'description')] 

render_template('file.html', form=form)

To render your form in file.html:

<form method="post">
    {{ form.hidden_tag() }}
    {{ form.radio_fields.label }}
    {{ form.radio_fields(style='list-style: none') }}
    {{ form.submit }}
</form>
Sign up to request clarification or add additional context in comments.

Comments

2

The base class FlaskForm is fairly particular about its construction. To define a dynamic form add the parameters after the base class has instantiated with super(). I.e.

class GenerateForm(FlaskForm):
    radio_fields = RadioField('', choices=[])
    submit = SubmitField('submit')

    def __init__(self, label, choices):
        super().__init__()
        self.radio_fields.choices = label
        self.radio_fields.choices = choices

Then you can instantiate the form with:

GenerateForm('My Label', [('val', 'desc'), ('val2', 'desc2')])]

You can also create a Form Factory in the following way:

def Form(n, *args):
    class FormGenerator(FlaskForm):
        submit = SubmitField('submit')

    for i in range(n):
        setattr(FormGenerator, RadioField(args[i][0], choices=args[i][1])

    return FormGenerator()

Then you can instantiate the form with:

Form(2, *(('rad1', [('v1', 'd1'), ('v2', 'd2')]), ('rad2', [('v1', 'd1'), ('v2', 'd2')])))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.