Skip to content

Instantly share code, notes, and snippets.

@doobeh
Created January 19, 2016 14:04
Show Gist options
  • Save doobeh/5d0f965502b86fee80fe to your computer and use it in GitHub Desktop.
Save doobeh/5d0f965502b86fee80fe to your computer and use it in GitHub Desktop.
More complete example of FieldList with FormField
<form method="post" action="">
{{ form.name}}
{{ form.hidden_tag() }}
<br/>
{% for entry in form.hours %}
{{ loop.index0|dow }}
{{ entry() }}
{% endfor %}
<input type="submit"/>
</form>
from flask import Flask, render_template
from flask_wtf import Form
from wtforms import StringField, FormField, FieldList, HiddenField
import calendar
app = Flask(__name__)
app.secret_key = 'SCRATCH'
def dow_name(dow):
return calendar.day_name[dow]
app.jinja_env.filters['dow'] = dow_name
class TimeForm(Form):
opening = StringField('Opening Hour')
closing = StringField('Closing Hour')
day = HiddenField('Day')
class BusinessForm(Form):
name = StringField('Business Name')
hours = FieldList(FormField(TimeForm), min_entries=7, max_entries=7)
@app.route('/', methods=['post','get'])
def home():
form = BusinessForm()
if form.validate_on_submit():
results = []
for idx, data in enumerate(form.hours.data):
results.append('{day}: [{open}]:[{close}]'.format(
day=calendar.day_name[idx],
open=data["opening"],
close=data["closing"],
)
)
return render_template('results.html', results=results)
print(form.errors)
return render_template('home.html', form=form)
if __name__ == '__main__':
app.run(debug=True)
<ul>
{% for line in results %}
<li>{{ line }}</li>
{% endfor %}
</ul>
@asmith26
Copy link

Thank you very much, helped me a lot.

@BlkPingu
Copy link

I'm not sure what I'm looking at here. Could you write a few sentences about it?

@ethagnawl
Copy link

If you ever revisit this, it'd be extremely helpful to see how you instantiate and persist the nested TimeForms.

@doobeh
Copy link
Author

doobeh commented Mar 4, 2020

Is your question 'How do I store this in a database?' and then '... and display it for editing' later? If you want to explain your goal (or even your particular problem and goal) I can probably elaborate a bit.

@ethagnawl
Copy link

Thanks for the prompt response! I was just wondering if there was a simple, uniform way to use the nested form object to populate a new instance of a model. I was figuring that WTForms would handle this mapping (via something like its populate_obj method), but I can't seem to get that to work with FormField instances.

@doobeh
Copy link
Author

doobeh commented Mar 4, 2020

I can't say I've ever tried- but I might give it a kick a bit later, seems like it should be possible 🤞
I'll probably do an example like 'a sports team' has several 'players' type setup, unless you can think of a better scenario.

No promises!

@ethagnawl
Copy link

Hey! That'd be great and I think it'd be very valuable to the community.

I wound up finding a workable solution where I manually pluck values off of the nested form object and create a new model instance, but I suspect there is a more elegant solution:

    if form.validate_on_submit():
        try:
            form.populate_obj(some_obj) # this is the containing form/mapped model
            nested_obj = NestedObj(
                note=form.nested_forms[0].data['note'],
            )
            db.session.add(nested_obj)
            db.session.commit()
...

@doobeh
Copy link
Author

doobeh commented Mar 4, 2020

Check out https://gist.github.com/doobeh/aa0e07892922cfa32123a6926c7720a5 and throw any questions you have there (I might have missed something obvious!)

@pascale64
Copy link

pascale64 commented Mar 6, 2020

Hi it will be very helpfull to me too!!!
I have just found your code, it's great! But I dont understand the
``def dow_name(dow):
return calendar.day_name[dow]

app.jinja_env.filters['dow'] = dow_name
If you can help, like your code I have two forms the first is a formfield of the second, I want to repeat this 1 to 6 times but I am unsure of how the function and filter works, Are you able to elaborate a bit?

@pascale64
Copy link

Hi I have now understood the function and filter from using your code, But I need help if possible,

@doobeh
Copy link
Author

doobeh commented Mar 7, 2020

The filter was more to give some data formatting on the template... it essentially just did a dict lookup {0: 'Monday', 1: 'Tuesday', ...} so the number provided by the index0 loop (0,1,2,3,4,5 ...) resolved to a word.
Feel free to post up an example of what you're having problems with-- and drop the link in here. Hopefully the https://gist.github.com/doobeh/aa0e07892922cfa32123a6926c7720a5 example can provide more examples (without the filter confusing things)

@pascale64
Copy link

pascale64 commented Mar 7, 2020 via email

@giacomomarchioro
Copy link

I don't think it uses good practices because Form does not contains any CSRF token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment