Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
ModelFieldList for one-page forms
Problem
In WTForms-SQLAlchemy, there is currently no way of modeling nested forms based on from database models. Thus, in a One to Many database relationship, each of these relationship entries need their own form. Instead, it might be much more user friendly to be able to edit this relationship in a single form, with fields for each of the parent attributes, and a nested form containing entries of the database relationship.
Solution proposal
By creating a new field, ModelFieldList, I made it possible to render one to many relationships in a single form, where children are rendered as entries in nested forms. The nested forms are rendered with an 'add' and 'delete' buttons for each entry, which makes it easy to delete and/or add rows. On submitting the form, changes are updated in the database session. This field is now included in the converter for model_form().
Design
I created the following ModelFieldList class, which inherits from wtforms.fields.core.FieldList:
class wtforms_sqlalchemy.fields.ModelFieldList(unbound_field, horizontal_layout=False, model=None, label=None, validators=None, min_entries=0, max_entries=None, default=tuple(), /, *, label=None, validators=None, min_entries=0, max_entries=None, default=tuple(), filters=tuple(), description='', id=None, widget=None, render_kw=None, _form=None, _name=None, _prefix='', _translations=None, _meta=None)
model - The SQLAlchemy database model that serves as the base for the entries in the fieldlist.
horizontal_layout - When set to True, ModelFieldList will be rendered with a table that contains in the first row the fieldnames and in the second row the fields. When set to the default (False), fieldnames will appear in the table head, and fields appear below their proper fieldname for each entry.
I also created the following widget to work with the ModelFieldList class:
wtforms_sqlalchemy.fields._ModelFieldListTableWiget(horizontal_layout, prefix_label=True, with_table_tag=True)
I edited the following method:
wtforms_sqlalchemy.orm.model_form(model, db_session=None, base_class=<class 'wtforms.form.Form'>, only=None, exclude=None, field_args=None, converter=None, exclude_pk=True, exclude_fk=True, type_name=None, embed=False)
Sample usage
I created a demo of the implemented feature on repl.it, which you can check out here: https://modelfieldlist.pnehkan.repl.co/
Usage of the feature is demonstrated below.