Flask and WTForms - how to get wtforms to refresh select data

flask, python, wtforms

Solution

The problem is that `getAgencyList()` is called upon definition of the class. So whatever that function returns at that time will be it's data. In order to update the list information you have to somehow run `getAgencyList` during instantiation. In order to do this you can use a not very obvious fact about wtforms that allows you to add choices to a particular field. The documentation is here just look for the subsection that is titled "Select fields with dynamic choice values". Here's a sample of code that should work.

class CreateUserForm(Form):
    first_name = TextField()
    last_name = TextField()
    email = TextField('Email', 
            [validators.Length(min=6, max=120), validators.Email()])
    user_role = SelectField(u'User Role', 
            choices=[('1', 'User'), ('2', 'Admin')])
    org_role = SelectField(u'User Role', 
            choices=[('1', 'Agency'), ('2', 'Advertiser'),('3', 'Admin')])
    agency = SelectField(u'Agency')

    @classmethod
    def new(cls):
        # Instantiate the form
        form = cls()

        # Update the choices for the agency field
        form.agency.choices = getAgencyList()
        return form

# So in order to use you do this ...
@app.route('/someendpoint')
def some_flask_endpoint():
    # ... some code ...
    form = CreateUserForm.new()
    # That should give you a working CreateUserForm with updated values.
    # ... some more code to validate form probably...

Problem

I am using the latest version of flask, wtforms and Flask-WTForms. I have a page that displays a form and one is a select box with option option called "A". When the app starts all is well. In a another form I add a record called "B". Now, the form I want should have the select box wth options A and B bot only option A is available. I have to kill uWSGI and restart to get wtforms to refresh the data. So, what am I missing? How to I get wtforms to refresh data? Here s how I create the form where getAgencyList returns a list of options to add to the select box. In another dialogue I add an agency and the agency list should be updated without having to restart the app: ``` class createUser(Form): """ Users are given a default password """ first_name = TextField() last_name = TextField() email = TextField('Email', [validators.Length(min=6, max=120), validators.Email()]) user_role = SelectField(u'User Role', choices=[('1', 'User'), ('2', 'Admin')]) org_role = SelectField(u'User Role', choices=[('1', 'Agency'), ('2', 'Advertiser'),('3', 'Admin')]) agency = SelectField(u'Agency', choices=getAgencyList()) ```

Original source