如何绑定flask-wtform UnboundField? [英] How do I bind an flask-wtform UnboundField?

查看:335
本文介绍了如何绑定flask-wtform UnboundField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个将产品发布到市场的应用程序.该市场上的每个产品类别都有不同的产品属性形式,例如,如果是电子产品,则存在电压,型号等字段. 我通过市场服务器通过json获取此信息. 首先,用户必须写下产品的名称及其主要类别,然后市场服务器预测自己的类别并返回给我它的属性. 这是响应示例:

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. 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.

现在,我需要创建一个动态表单以能够添加/编辑这些字段,因为每个类别具有不同的属性类型和数量. 每个字段都需要有一个ID,一个类型(可以是仅字符串或仅数字) 标签,最大长度以及value_type number_unit是否需要一个具有给定单位的SelectField的最大长度.

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.

我正在视图中获取此信息,并且在同一视图中,我创建了FlaskForm的子类,在其中我根据属性的类型创建了字段列表.

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.

   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,它将显示以下内容:

But this creates a bunch of 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 %}

如何绑定UnboundField?

How do I bind an UnboundField?

推荐答案

要使用wtforms创建动态表单,请使用以下模板

To create a dynamic form with wtforms use the following template

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

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

    return StaticForm()

这将在函数的本地范围内建立一个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:

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

文档中的某处对此进行了解释,但是我现在找不到链接

This is explained in the docs somewhere, but I cant find the link right now

这篇关于如何绑定flask-wtform UnboundField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆