我正在创建一个将产品发布到市场的应用程序。这个市场上的每个产品类别都有不同的产品属性形式,例如,如果是电子产品,则存在电压,型号等字段。 我通过市场服务器通过json获取此信息。 首先,用户必须输入产品的名称及其主要类别,然后市场服务器预测自己的类别并返回其属性。 这是响应示例:
{
"id": "MODEL",
"name": "Modelo",
"tags": {
"hidden": true
},
{
"id": "PACKAGE_LENGTH",
"name": "Comprimento da embalagem",
"tags": {
"hidden": true,
"read_only": true,
"variation_attribute": true
},
"hierarchy": "ITEM",
"relevance": 2,
"value_type": "number_unit",
"value_max_length": 255,
"allowed_units": [
{
"id": "km",
"name": "km"
},
{
"id": "polegadas",
"name": "polegadas"
},
{
"id": "ft",
"name": "ft"
},
{
"id": "mm",
"name": "mm"
},
{
"id": "m",
"name": "m"
},
{
"id": "\"",
"name": "\""
},
{
"id": "in",
"name": "in"
},
{
"id": "cm",
"name": "cm"
}
],
"default_unit": "cm",
"attribute_group_id": "OTHERS",
"attribute_group_name": "Outros"
}
到目前为止,一切都很好。
现在,我需要创建一个动态表单以能够添加/编辑这些字段,因为每个类别具有不同的属性类型和数量。 每个字段都需要有一个ID,一个类型(可以是仅字符串或仅数字) 标签,最大长度以及value_type number_unit是否需要使用给定单位的SelectField。
我正在视图中获取此信息,并且在同一视图中,我创建了FlaskForm的子类,在其中我根据属性的类型创建了字段列表。
class DynamicForm(PostProductForm):
loaded_attr = json.loads(meli.get(f"/categories/{category}/attributes").content.decode('utf-8'))
attribute_fields = []
for attribute in loaded_attr:
tags = attribute.get('tags')
if not tags.get('read_only'):
if attribute.get('value_type') == 'number_unit':
attribute_fields.append(IntegerField(
attribute['name'], validators=[Length(min=0, max=attribute['value_max_length'])]))
allowed_units = [(unit['id'], unit['name']) for unit in attribute['allowed_units']]
attribute_fields.append(SelectField('Unidade', choices=allowed_units))
elif attribute['value_type'] == 'string':
attribute_fields.append(StringField(
attribute['name'], validators=[Length(min=0, max=attribute['value_max_length'])]))
elif attribute['value_type'] == 'number':
attribute_fields.append(IntegerField(
attribute['name'],
validators=[Length(min=0, max=attribute['value_max_length'])]))
elif attribute['value_type'] == 'boolean':
attribute_fields.append(BooleanField(attribute['name']))
但这会创建一堆UnboundFields。如果我仅尝试呈现每个字段repr,它将显示以下内容:
<UnboundField(StringField, ('SKU ',), {'validators': [<wtforms.validators.Length object at 0x04DFBEF0>]})>
如果我尝试渲染该字段,则会给我一个例外:
TypeError: 'UnboundField' object is not callable
我正在遍历模板中的列表。
{% for attribute in form.attribute_fields %}
<div class="form-group blocked">
{{ attribute() }}
</div>
{% endfor %}
如何绑定UnboundField?
答案 0 :(得分:0)
要使用wtforms创建动态表单,请使用以下模板
def DynamicForm(*args, **kwargs):
class StaticForm(FlaskForm):
pass
if args[0] == True:
StaticForm.class_attrib1 = StringField(...)
else:
StaticForm.class_attrib2 = StringField(...)
return StaticForm()
这将在函数的本地范围内建立一个StaticForm,根据来自函数参数的编程逻辑附加所有相关项,并返回实例化的形式:
form = DynamicForm(True)
# form has attribute: class_attrib1
文档中的某处对此进行了解释,但是我现在找不到链接