Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python WTForm:FieldList和SelectField,如何渲染?_Python_Flask_Wtforms_Flask Wtforms - Fatal编程技术网

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
    添加到您的to
    OrderForm

    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