dynamic-flask-form
dynamic-flask-form copied to clipboard
Dynamic Flask Form
Having struggled to find a workind example of a WTForm in Flask with a dynamic form, I created this one. It is cobbled together from a few Stackoverflow and Google Group discussions.
I'm a total noob so if you have suggestions I'd be glad to include them!
What does it do?
- Render a form with two models
- Save and load the related models
This means you can have a form with dynamically created fields which are saved and loaded properly.
Usage
You can use requirements.txt to install the packages, preferably in a virtualenv. Then you can simply run multimodel.py. The default port is set to 5002.
Basic Concepts
- FieldList and FormField are used to nest one Form inside another
-
phones
is a relation in theUser Model
creating a link toPhone entries
. -
PhoneForm
deals with the Phone fields only -
CombinedForm
includes theUser
andPhone
fields - The
CombinedForm
is populated through theUser
model and relatedphones
Pain Points
User Model
I had named the phones
relation phone
for a while which broke the populate_obj
function. The naming must match for the mechanism to work. Duh.
PhoneForm
This is the form that is nested in the 'main' Form. It is not directly exposed or rendered. A common problem here is the CSRF token being missing from this form. Options to solve this problem are explained here. I chose to subclass wtforms Form which does not require the token.
CombinedForm
phones = FieldList(FormField(PhoneForm, default=lambda: Phone()))
That is the line of code where it all broke down for me. Once there is a working
example it's hopefully not so mysterious. Setting the default to lambda: Phone()
was difficult for me to get to (see Fixing populate_obj)
Index
I just load the one user from the db, no messing around. Playing with a dropdown for different users just distracts from the main point here.
I'm not sure if aassing a new Phone instance where the User has no phones is the best possible solution but it meant I could keep using the JavaScript Code as it was.
Javascript
I simply fixed example code that I found. There is probably a neater way of copying the fields that I haven't found. I would gladly take suggestions in this case as well as the rest of the code.
Resources
Half working example Fixing populate_obj Error display in View FormField Documenation