python - WTForm : FieldList with SelectField, 如何渲染?

标签 python flask wtforms flask-wtforms

我有这个订单表格,允许我的用户创建订单。一个订单由 (producetype, quantity) 的多个元组组成. Producetype 应在 <select> 中呈现形式而数量可以只是一个输入。 producetype 的选择应该动态添加,因为它可能会改变。目前,我已经用纯 html 编写了这个

enter image description here

我想为此使用 WTForm,因为 WTForm 确实简化了我的代码。但是,我无法这样做:

代码:

class OrderEntryForm(Form):
  quantity = IntegerField('Quantity',
                          [validators.Required(), validators.NumberRange(min=1)])
  # we will be dynamically adding choices
  producetype = SelectField('Produce',
                            [validators.Required()],
                            choices=[])

class OrderForm(Form):
  name = TextField('Crop', [validators.Length(min=3, max=60)])
  due_date = DateField('Due Date', [validators.required()])
  order_entries = FieldList(FormField(OrderEntryForm))

我有以下问题:

  1. 如何动态地向 order_entries 添加选项OrderForm 的字段?
  2. 如果我有订单,order = { name:hello, due_date:2014-06-18, order_entries:[ {producetype_id: 1, quantity: 2}, {producetype_id: 3, quantity: 4}] } , 如何填充我的 OrderForm右边OrderEntryForm值(value)观?

最佳答案

How can I dynamically add choices to the order_entries field of the OrderForm

这取决于你的意思

如果你的意思是你想在渲染后向表单添加行项目。您必须使用 DOM 操作在客户端添加这些。 WTForms 有一个命名约定,用于处理表单字段上的索引。它只是name="<form-field-name>-<index>" .如果您使用遵循此约定的 javascript 添加名称,WTForms 将知道如何在后端处理它。

如果你的意思是你想要一个动态选择列表,那么你可以迭代 FieldList在其实例化后的形式中。您可以分配 choices任何可迭代的 2 元组。在下面的示例中,我直接分配它们,但它们可以很容易地从存储中检索。

order_form = OrderForm()
for sub_form in order_form.order_entries:
    sub_form.producetype.choices = [('2', 'apples'), ('2', 'oranges')]

how can populate my OrderForm with the right OrderEntryForm values?

您可以使用 obj 将对象直接绑定(bind)到表单关键字参数。 WTForms 足够智能,可以根据对象的属性动态构建表单。

from wtforms import Form, IntegerField, SelectField, TextField, FieldList, FormField
from wtforms import validators
from collections import namedtuple

OrderEntry = namedtuple('OrderEntry', ['quantity', 'producetype'])
Order = namedtuple('Order', ['name', 'order_entries'])

class OrderEntryForm(Form):
  quantity = IntegerField('Quantity',
                          [validators.Required(), validators.NumberRange(min=1)])
  # we will be dynamically adding choices
  producetype = SelectField('Produce',
                            [validators.Required()],
                            choices=[
                                (1, 'carrots'),
                                (2, 'turnips'),
                            ])

class OrderForm(Form):
  name = TextField('Crop', [validators.Length(min=3, max=60)])
  order_entries = FieldList(FormField(OrderEntryForm))

# Test Print of just the OrderEntryForm
o_form = OrderEntryForm()
print o_form.producetype()

# Create a test order
order_entry_1 = OrderEntry(4, 1)
order_entry_2 = OrderEntry(2, 2)

order = Order('My First Order', [order_entry_1, order_entry_2])

order_form = OrderForm(obj=order)

print order_form.name
print order_form.order_entries

上面的例子创建了一个样本 Order并将其提供给 obj关键词。在渲染时,这将生成以下内容(无样式):

enter image description here

关于python - WTForm : FieldList with SelectField, 如何渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24296834/

相关文章:

python - 图像转base64 : Why don't I get the same return value while calling the same function in Python?

python - Django 1.8 中的正则表达式 urlconf 将不起作用

python - 如何检测 POST 请求(flask)上的错误?

python - 使用 SQLAlchemy(MySQL) 和 Flask 时 MySQL 连接不可用

python - WTForms 上的 UnicodeDecodeError

python - WTForms 得到错误

python - 如何从 .xlsx 文件的内容获取字典?

python - 最后的列表元素和条件循环

python - 如何使 Flask 客户端看起来像是测试机的外部?

python - Flask Wtforms FileField 对象没有读取属性