Dynamic forms (forms) in a flask / WTForms?

In Django, you have a function with multiple forms called Formsets, which you can use to create multiple forms in a single template. I am trying to achieve something similar in 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> 

The idea has one form that wraps all the flags that the user wants to mark in order to make friends. Currently, I am not creating a form class in Flask, since I do not know how to make a dynamic FormSet, so I dynamically create a form inside html.

Caution, however, I do not know how to retrieve the selected user id using the checkbox. (I saved it in id because I did not know better)

But I cannot access id in request.values['checkbox1'] . I can only see it on or off .

Any suggestions on how to resolve this, please?

+4
source share
2 answers

Problem

Your problem is that id not sent back to the server - only value is ... and since your flags do not have the value attribute, the default value is used, which, as it turned out, is t23>.

Since you noted this with , I will give you an example of how you could do this.

Never repeat this problem

There is a class in the WTForms documentation that will create a list of flags 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() 

You should use this field in your user form as follows:

 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) 

Then in friends.html you can form.potential_friends over the form.potential_friends field:

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

You can customize the HTML inside the for loop. My specific example should display (with a few attributes like for and name ):

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

I personally added a hidden input field under each flag box with a name like โ€œfriend_nametag1โ€ and a value corresponding to the friendโ€™s identifier in the hidden input field. By adding 1 for each "friend". So you can watch it as a flask using something like

 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') 

Obviously, you can use some logic to have an incremental index (in this case, โ€œ1โ€ in โ€œcheckbox1โ€).

I am not too familiar with WTForms, so there may be a better way to do this, but this solution is pretty simple to implement with your current code.

If you want to use FieldSet or FormSet, I would suggest using FormField in conjunction with FieldList with the relevant documents here: http://wtforms.simplecodes.com/docs/dev/fields.html#field-enclosures

ps: I would not recommend using request as the variable name in your template or your code, as this can obscure the global request jar? Xd

0
source

Source: https://habr.com/ru/post/1496595/


All Articles