-
-
Save doobeh/5d0f965502b86fee80fe to your computer and use it in GitHub Desktop.
<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> |
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.
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.
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!
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()
...
Check out https://gist.github.com/doobeh/aa0e07892922cfa32123a6926c7720a5 and throw any questions you have there (I might have missed something obvious!)
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?
Hi I have now understood the function and filter from using your code, But I need help if possible,
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)
I don't think it uses good practices because Form does not contains any CSRF token.
If you ever revisit this, it'd be extremely helpful to see how you instantiate and persist the nested TimeForms.