Flask / WTForms中的动态表单(Formsets)?

时间:2013-08-12 13:36:22

标签: flask wtforms flask-wtforms

在Django中,您有一个名为Formsets的多表单功能,您可以使用它在同一模板中创建多个表单。我正在尝试在Flask / WTforms中实现类似的功能。

<form action="{{ url_for('request-accept') }}" method='post'>           
   <table>
        <tbody>
            {% for request in requests %}
                    <tr>                    
                        <td>                        
                           <div class="person-header">
                              <img src="{{request.profile_pic_url}}" class="img-circle profile-image"/>
                              <p class="person-header-text">{{request.fullname()}}</p>    
                           </div>
                       </td>                
                       <td>
                           <input type="checkbox" id="{{request.key.urlsafe()}}" name="checkbox{{loop.index}}">
                       </td>                    
                   </tr>
           {% endfor %}
    </tbody>            
  </table>

  <input class='submit btn btn-primary' type=submit value="Connect">            
</form>

这个想法是让一个表单包含所有复选框,用户喜欢勾选这些复选框。目前看来我并没有在Flask中生成任何表单类,因为我不知道如何创建动态FormSet,因此我在html中动态创建表单。

但需要注意的是,我不知道如何通过复选框检索选定的user id。 (我已将其存储在id,因为我不知道更好)

但我无法访问request.values['checkbox1']中的ID。我只能查看其onoff

任何建议如何解决这个问题?

2 个答案:

答案 0 :(得分:11)

问题

您的问题是id没有被发送回服务器 - 只有value是......而且由于您的复选框 没有value }属性使用默认值,恰好是on

由于您使用对此进行了标记,因此我将举例说明 可以这样做。

再也没有这个问题

WTForms的文档有example class that will create a list of checkboxes for you

class MultiCheckboxField(SelectMultipleField):
    """
    A multiple-select, except displays a list of checkboxes.

    Iterating the field will produce subfields, allowing custom rendering of
    the enclosed checkbox fields.
    """
    widget = widgets.ListWidget(prefix_label=False)
    option_widget = widgets.CheckboxInput()

您可以这种方式在自定义表单中使用此字段:

class FriendsForm(Form):
    potential_friends = MultiCheckboxField("Friends", coerce=int)

# ... later ...

@app.route("/add-friends", methods=["GET", "POST"])
def add_friends():
    form = FriendsForm(request.form)
    # lookup friends, for now we'll use a static list
    form.potential_friends.choices = [(1, "Sam"), (2, "Joe")]

    # We'll also need a mapping of IDs to Person instances
    # (Made up for this example - use your own ;-) )
    mapping = {
        1: Person("Sam", profile_pic="sam.jpg"),
        2: Person("Joe", profile_pic="joe.png")
    }

    if request.method == "POST":
        # Mark new friends

    return render_template("friends.html", form=form, persons=mapping)

然后,在friends.html中,您可以遍历form.potential_friends字段:

{% for person in form.potential_friends %}
    persons[person.data].profile_pic :: {{person.label}} :: {{person}}<br>
{% endfor %}

您可以在for循环内自定义HTML。我的特定示例应该呈现(还有一些属性,例如forname):

sam.jpg :: <label>Sam</label> :: <input type="checkbox" value="1">
joe.png :: <label>Joe</label> :: <input type="checkbox" value="2">

答案 1 :(得分:0)

我个人会在每个复选框下的字段集中添加一个hidden输入字段,其名称如&#34; friend_nametag1&#34;以及与朋友的ID相对应的值。随着每个&#34;朋友&#34;增加1。因此,您可以使用类似

之类的东西在烧瓶视图中查找它
friend_list = []
list_of_checkboxes = ... (fetch from request.form... ?)
dict_of_friend_nametags = ... (build from request.form... ?)
if 'checkbox1' in list_of_checkboxes:
    friend_list.append(dict_of_friend_nametags.get('friend_nametag1')

显然,您可以使用某种逻辑来获得增量索引(&#34; 1&#34; in&#34; checkbox1&#34;在这种情况下)。

我对WTForms不太熟悉,所以可能有更好的方法来实现这一点,但是使用当前代码实现这个解决方案非常简单。

如果您需要FieldSet或FormSet,我建议您将FormField与FieldList一起使用,并在此处使用相关文档:http://wtforms.simplecodes.com/docs/dev/fields.html#field-enclosures

p.s。:我建议不要在模板或代码中使用request作为变量名,因为它可能会影响烧瓶的全局request? XD