Python WTForm:FieldList和SelectField,如何渲染?
我有一个订单表单,允许我的用户创建订单。订单由多个Python WTForm:FieldList和SelectField,如何渲染?,python,flask,wtforms,flask-wtforms,Python,Flask,Wtforms,Flask Wtforms,我有一个订单表单,允许我的用户创建订单。订单由多个(producetype,quantity)元组组成。Producetype应以形式呈现,而quantity只能作为输入。producetype的选项应该动态添加,因为这可能会改变。目前,我已经用纯html编写了这篇文章 我想使用WTForm来实现这一点,因为WTForm确实简化了我的代码。但是,我不能这样做: 代码: 我有以下问题: 如何向订单的order\u条目字段动态添加选项 如果我有订单,order={name:hello,到期日:20
(producetype,quantity)
元组组成。Producetype应以
形式呈现,而quantity只能作为输入。producetype的选项应该动态添加,因为这可能会改变。目前,我已经用纯html编写了这篇文章
我想使用WTForm来实现这一点,因为WTForm确实简化了我的代码。但是,我不能这样做:
代码:
我有以下问题:
order\u条目
字段动态添加选项order={name:hello,到期日:2014-06-18,订单条目:[{producetype\u id:1,数量:2},{producetype\u id:3,数量:4}]}
,如何用正确的OrderEntryForm
值填充我的OrderForm
将
SubmitField
添加到您的toOrderForm
:
submit_something = SubmitField((u'Add something'))
然后从您的视图中调用它,并使用字段列表的附加项方法:
if form.submit_something.data:
form.order_entries.append_entry()
return render_template('yourtemplate.html', form=form)
希望有帮助
如何向OrderForm的order_entries字段动态添加选项
这取决于你的意思
如果您的意思是要在渲染后将行项目添加到窗体中。您必须使用DOM操作在客户端添加这些。WTForms有一个命名约定,用于寻址表单字段上的索引。它只是name=“-”
。如果使用遵循此约定的javascript添加名称,WTForms将知道如何在后端处理它
如果您的意思是希望有一个动态选择列表,那么您可以在实例化后在表单中迭代字段列表
。您可以指定选项
任何2元组的iterable。在下面的示例中,我直接分配它们,但它们也可以很容易地从存储中检索
order_form = OrderForm()
for sub_form in order_form.order_entries:
sub_form.producetype.choices = [('2', 'apples'), ('2', 'oranges')]
如何使用正确的OrderEntryForm值填充我的OrderForm
您可以使用obj
关键字参数直接将对象绑定到表单。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
关键字。渲染时,将生成以下内容(未设置样式):
对于其他被SelectField
s+FieldList
s难倒的人,这就是我用SelectField
s实现FieldList
的方法(灵感来源于)。这种方法基于JSON数据动态地向/home
路由呈现任意数量的SelectFields
路线(routes.py):
@app.route('/home',methods=['POST',GET']
def home():
自定义元数据=数据
选择元数据表单列表=选择表单列表()
选择元数据表单列表。选择条目=获取选择条目()
上下文={
“选择元数据表单列表”:选择元数据表单列表,
}
返回呈现模板('home.html',**上下文)
表格(forms.py):
class选择表单(烧瓶表单):
选择=选择字段(“占位符”,选项=[])
类别选择表单列表(烧瓶表单):
选择\条目=字段列表(FormField(SelectForm))
模板(home.html
):
{%用于选择元数据表单列表中的选择表单。选择条目%}
{{select\u form.select.label}}:{{{select\u form.select}}
{%endfor%}
助手方法(app.py):
def get_select_entries():
"""
将自定义元数据转换为forms.SelectForm(),然后可以
SelectFormlist()用于动态呈现选定项。
:返回:
"""
select_data=get_select_data_from_custom_metadata()
选择\u数据\u标记=获取\u标记\u选择\u数据(选择\u数据=选择\u数据)
所有选择项=[]
对于select_data_标签中的select_dict:
对于k,v,在select_dict.items()中:
select_id=uuid.uuid1()#允许多次选择
选择条目=选择表格()
选择_entry.select.label=k
选择\u entry.id=选择\u id
选择_entry.select.choices=v
所有选择项。附加(选择项)
返回所有选定项目
def get_select_data_from_custom_metadata():
"""
[
{“资历”:[“实习生”、“助理”、“高级”]}
]
:return:包含键和选择值列表的词典列表
"""
type=“选择”
选择_data=[]
自定义\u元数据=获取\u自定义\u元数据()
对于自定义_元数据中的字段[“字段”]:
如果字段[“类型”]==类型:
选择_data.append({field[“key”]:field[“data_list”]})
返回选择数据
数据(custom\u metadata.json):
{
“字段”:[
{
“类型”:“文本”,
“键”:“位置”
},
{
“类型”:“选择”,
“关键”:“资历”,
“数据清单”:[“实习生”、“助理”、“高级”、“高管”]
},
{
“类型”:“选择”,
“密钥”:“公司”,
“数据列表”:[“福特”、“雪佛兰”、“丰田”]
},
{
“类型”:“选择”,
“关键”:“团队”,
“数据列表”:[“雄鹿”、“猛禽”、“雷霆”]
}
]
}
结果:
这非常有帮助。非常感谢。但是,我还有一个问题与您的解决方案直接相关。请你也看一下好吗?如何设置样式以消除订单条目-0等?您可以添加与内联的样式来呈现字段,只需调用它,并提供小部件期望作为关键字参数的任何值。通常,关键字参数用于额外的HTML属性。
或者,您可以像处理HTML/css时通常那样,在文档中添加样式表。
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