简体   繁体   English

如何绑定flask-wtform UnboundField?

[英]How do I bind an flask-wtform UnboundField?

I am creating an app to post products to a marketplace. 我正在创建一个将产品发布到市场的应用程序。 Each product category on this marketplace has a different form for product attributes, for example if it's electronic there are fields for voltage, model number... I get this information via json through the marketplace server. 该市场上的每个产品类别的产品属性都有不同的形式,例如,如果是电子产品,则存在电压,型号等字段。我可以通过市场服务器上的json获取此信息。 First the user has to write the name of the product and it's main category and the marketplace server predicts their own category and returns to me it's attributes. 首先,用户必须输入产品的名称及其主要类别,然后市场服务器预测自己的类别并返回其属性。 Here's an example of the response: 这是响应示例:

{
"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"
}

So far so good. 到现在为止还挺好。

Now I need to create a dynamic form to be able to add/edit those fields because each category has a different type of attribute, and different amount. 现在,我需要创建一个动态表单,以便能够添加/编辑这些字段,因为每个类别都有不同的属性类型和数量。 Each field needs to have an ID, a type (could be string only, or numbers only) an label, and a max length and if its of value_type number_unit needs a SelectField with the given units. 每个字段都需要有一个ID,一个类型(只能是字符串,或者只能是数字),一个标签以及一个最大长度(如果其value_type number_unit需要一个具有给定单位的SelectField)。

I'm getting this information in a view, and at the same view I create a subclass of a FlaskForm, where I create a list of fields based on the type of the attribute. 我正在一个视图中获取此信息,并且在同一视图中,我创建了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']))

But this creates a bunch of UnboundFields. 但这会创建一堆UnboundFields。 If I try to render only each field repr it shows me this: 如果我尝试仅渲染每个字段代表,它将显示以下内容:

<UnboundField(StringField, ('SKU ',), {'validators': [<wtforms.validators.Length object at 0x04DFBEF0>]})>

If I try to render the field it gives me an exception: 如果我尝试渲染该字段,则会给我一个例外:

TypeError: 'UnboundField' object is not callable

I am looping through the list inside the template. 我正在遍历模板内的列表。

    {% for attribute in form.attribute_fields %}
    <div class="form-group blocked">
        {{ attribute() }}
    </div>
    {% endfor %}

How do I bind an UnboundField? 如何绑定UnboundField?

To create a dynamic form with wtforms use the following template 要使用wtforms创建动态表单,请使用以下模板

def DynamicForm(*args, **kwargs):
    class StaticForm(FlaskForm):
        pass

    if args[0] == True:
        StaticForm.class_attrib1 = StringField(...)
    else:
        StaticForm.class_attrib2 = StringField(...)

    return StaticForm()

This establishes a StaticForm within the local scope of the function, attaches all of the relevant items based on programming logic from the function arguments and returns an instantiated form: 这将在函数的本地范围内建立一个StaticForm,根据来自函数参数的编程逻辑附加所有相关项,并返回实例化形式:

form = DynamicForm(True)
# form has attribute: class_attrib1

This is explained in the docs somewhere, but I cant find the link right now 在某处的文档中对此进行了解释,但是我现在找不到链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM