5

在 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']. 我只能看到它的onoff

有什么建议可以解决这个问题吗?

4

2 回答 2

11

问题

您的问题是id未将其发送回服务器-仅是 ... 并且由于您的value复选框没有属性,因此value使用默认值,恰好是on.

既然你用标记了它,我会给你一个例子来说明你如何做到这一点。

再也没有这个问题

WTForms 的文档有一个示例类,它将为您创建一个复选框列表

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">
于 2013-08-16T06:58:17.240 回答
0

我个人会hidden在每个复选框下的字段集中添加一个输入字段,其名称如“friend_nametag1”和对应于朋友 ID 的值。每个“朋友”都会增加 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')

显然,您可以使用某种逻辑来获得增量索引(在这种情况下,“checkbox1”中的“1”)。

我对 WTForms 不太熟悉,所以可能有更好的方法来做到这一点,但是这个解决方案很容易用你当前的代码实现。

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

ps:我不建议request在模板或代码中使用变量名,因为它可能会request影响 flask 的全局?XD

于 2013-08-12T19:49:32.713 回答