-
-
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> |
I'm not sure what I'm looking at here. Could you write a few sentences about it?
If you ever revisit this, it'd be extremely helpful to see how you instantiate and persist the nested TimeForms.
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.
Thank you very much, helped me a lot.