Python 如何在 WTForms 中生成动态字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12850605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:00:23  来源:igfitidea点击:

How do I generate dynamic fields in WTForms

pythonflaskwtforms

提问by ChiliConSql

I am trying to generate a form in WTForms that has dynamic fields according to this documentation http://wtforms.simplecodes.com/docs/1.0.2/specific_problems.html#dynamic-form-composition

我正在尝试根据此文档在 WTForms 中生成一个具有动态字段的表单http://wtforms.simplecodes.com/docs/1.0.2/specific_problems.html#dynamic-form-composition

I have this subform class which allows users to pick items to purchase from a list:

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

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

class F(Form):
        pass

There will be more than one category of shopping items, so I would like to generate a dynamic select field based on what categories the user will choose:

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

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

but I get the following error:

但我收到以下错误:

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

Am I doing something wrong, or is there no way to accomplish this in WTForms?

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

回答by Ignas But?nas

Posting without writing full code or testing the code, but maybe it will give you some ideas. Also this could maybe only help with the filling the needed data.

无需编写完整代码或测试代码即可发布,但也许会给您一些想法。此外,这可能只能帮助填充所需的数据。

You need to fill choicesfor SelectFieldto be able to see the data and be able to select it. Where you fill that? Initial fill should be in the form definition, but if you like dynamic one, I would suggest to modify it in the place where you creating this form for showing to the user. Like the view where you do some form = YourForm()and then passing it to the template.

您需要填写choicesSelectField是能够看到的数据,并能选择它。你在哪里填的?初始填写应该在表单定义中,但如果你喜欢动态的,我建议你在创建这个表单的地方修改它以显示给用户。就像您执行一些操作form = YourForm()然后将其传递给模板的视图一样。

How to fill form's select field with choices? You must have list of tuples and then something like this:

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

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

categorieshere must be dictionary containing your categories in format like {1:'One', 2:'Two',...}

categories这里必须是包含您的类别的字典,格式如下 {1:'One', 2:'Two',...}

So if you will assign something to choices when defining the form it will have that data from the beginning, and where you need to have user's categories, just overwrite it in the view.

因此,如果您在定义表单时将某些内容分配给选项,它将从一开始就拥有该数据,以及您需要在何处拥有用户类别,只需在视图中覆盖它即可。

Hope that will give you some ideas and you can move forward :)

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

回答by Matt Carrier

I ran into this issue tonight and ended up with this. I hope this helps future people.

我今晚遇到了这个问题并最终解决了这个问题。我希望这对未来的人有帮助。

RecipeForm.py

配方表格.py

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

views.py

视图.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)

I found this posthelpful as well

我发现这篇文章也很有帮助

回答by dezza

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)

I use the extended class BaseFormfor all my forms and have a convenient append_field function on class.

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

Returns the class with the field appended, since instances (of Form fields) can't append fields.

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

回答by John Ong

have you tried calling append_entry()on the form instance instead of the FieldList definition?

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

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

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

回答by lfzyx

WTForms Documentation: class wtforms.fields.SelectField

WTForms 文档类 wtforms.fields.SelectField

Select fields with dynamic choice values:

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

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')]

回答by Rohit

This is how i got it to work.

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

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)]

Strangely this whole thing stops working for me if i use coerce=int. I am myself a flaskbeginner, so i am not really sure why coerce=intcauses issue.

奇怪的是,如果我使用coerce=int. 我自己是flask初学者,所以我不确定为什么coerce=int会导致问题。