如何在WTForms中生成动态字段

时间:2012-10-12 00:28:42

标签: python flask wtforms

我正在尝试根据此文档{(3}}

在WTForms中生成具有动态字段的表单

我有这个子表单类,允许用户从列表中选择要购买的项目:

class Item(Form):
    itmid = SelectField('Item ID')
    qty = IntegerField('Quantity')

class F(Form):
        pass

将有多个购物项目类别,因此我想根据用户选择的类别生成动态选择字段:

fld = FieldList(FormField(Item))
fld.append_entry()

但是我收到以下错误:

AttributeError: 'UnboundField' object has no attribute 'append_entry'

我做错了什么,或者在WTForms中没有办法做到这一点?

6 个答案:

答案 0 :(得分:10)

我今晚遇到了这个问题并最终得到了这个。我希望这有助于未来的人们。

RecipeForm.py

class RecipeForm(Form):
    category = SelectField('Category', choices=[], coerce=int)
    ...

views.py

@mod.route('/recipes/create', methods=['POST'])
def validateRecipe():
    categories = [(c.id, c.name) for c in g.user.categories.order_by(Category.name).all()]
    form = RecipeForm(request.form)
    form.category.choices = categories
    ...

@mod.route('/recipes/create', methods=['GET'])
def createRecipe():
    categories = [(c.id, c.name) for c in g.user.categories.order_by(Category.name).all()]
    form = RecipeForm(request.form)
    form.category.choices = categories
    return render_template('recipes/createRecipe.html', form=form)

我发现此post也很有用

答案 1 :(得分:7)

class BaseForm(Form):
    @classmethod
    def append_field(cls, name, field):
        setattr(cls, name, field)
        return cls

from forms import TestForm
form = TestForm.append_field("do_you_want_fries_with_that",BooleanField('fries'))(obj=db_populate_object)

我为所有表单使用扩展类 BaseForm ,并在类上有一个方便的append_field函数。

返回附加了字段的类,因为(表单字段的)实例不能附加字段。

答案 2 :(得分:6)

在不编写完整代码或测试代码的情况下发布,但也许它会给你一些想法。这也许只会有助于填写所需的数据。

您需要为choices填写SelectField才能查看数据并能够选择数据。你填的那个?初始填充应该在表单定义中,但是如果您喜欢动态表单,我建议您在创建此表单的位置对其进行修改以向用户显示。就像您在其中执行某些form = YourForm()然后将其传递给模板的视图一样。

如何用选项填写表单的选择字段?你必须有元组列表,然后是这样的:

form.category_select.choices = [(key, categories[key]) for key in categories]
form.category_select.choices.insert(0, ("", "Some default value..."))

categories此处必须是包含您的类别的字典,格式为{1:'One', 2:'Two',...}

因此,如果您在定义表单时将某些内容分配给选项,那么它将从头开始拥有该数据,并且您需要拥有用户类别的位置,只需在视图中覆盖它。

希望能给你一些想法,你可以继续前进:)

答案 3 :(得分:1)

您是否尝试在表单实例上调用append_entry()而不是FieldList定义?

class F(Form)
  fld = FieldList(SelectField(Item))

form = F()
form.fld.append_entry()

答案 4 :(得分:1)

这就是我让它工作的方式。

class MyForm(FlaskForm):
    mylist = SelectField('Select Field', choices=[])

@app.route("/test", methods=['GET', 'POST']
def testview():
    form = MyForm()
    form.mylist.choices = [(str(i), i) for i in range(9)]

奇怪的是,如果我使用coerce=int,这整个事情对我来说将停止工作。我本人是flask的初学者,所以我不确定coerce=int为何会引起问题。

答案 5 :(得分:-1)

WTForms Documentation : class wtforms.fields.SelectField

选择具有动态选择值的字段:

class UserDetails(Form):
    group_id = SelectField(u'Group', coerce=int)

def edit_user(request, id):
    user = User.query.get(id)
    form = UserDetails(request.POST, obj=user)
    form.group_id.choices = [(g.id, g.name) for g in Group.query.order_by('name')]