简体   繁体   English

Flask和WTForms - 如何获取wtforms以刷新选择数据

[英]Flask and WTForms - how to get wtforms to refresh select data

I am using the latest version of flask, wtforms and Flask-WTForms. 我正在使用最新版本的flask,wtforms和Flask-WTForms。

I have a page that displays a form and one is a select box with option option called "A". 我有一个显示表单的页面,其中一个是带有选项选项的选择框,名为“A”。

When the app starts all is well. 当应用程序启动时,一切都很好。 In a another form I add a record called "B". 在另一种形式中,我添加了一个名为“B”的记录。

Now, the form I want should have the select box wth options A and B bot only option A is available. 现在,我想要的表单应该有选项框和选项A和B bot只有选项A可用。 I have to kill uWSGI and restart to get wtforms to refresh the data. 我必须杀死uWSGI并重新启动以获取wtforms来刷新数据。

So, what am I missing? 那么,我错过了什么? How to I get wtforms to refresh data? 如何让wtforms刷新数据?

Here s how I create the form where getAgencyList returns a list of options to add to the select box. 这是我如何创建表单,其中getAgencyList返回要添加到选择框的选项列表。 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())

The problem is that getAgencyList() is called upon definition of the class. 问题是在定义类时调用getAgencyList() 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. 为了更新列表信息,您必须以某种方式在实例化期间运行getAgencyList 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. 为了做到这一点,您可以使用一个非常明显的关于wtforms的事实,它允许您向特定字段添加选项。 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...

A simple solution would be to fetch the options to be displayed from the database and then overwrite the Form Class with those: 一个简单的解决方案是从数据库中获取要显示的选项,然后用以下内容覆盖Form Class:

eg: 例如:

def get_agencies():
    agency_list = []
    # get the Agencies from the database - syntax here would be SQLAlchemy
    agencies = Agency.query.all()
    for a in agencies:
        # generate a new list of tuples
        agency_list.append((a.id,a.name))
    return agency_list

@app.route('/somewhere',methods=['POST'])
def somewhere():
    form = createUser()
    # overwrite the choices of the Form Class
    form.agency.choices = get_agencies()
    # here goes the rest of code - like form.validate_on_submit()
    ...
    return render_template('create_user.html', form=form)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM