pallets-eco / flask-admin

Simple and extensible administrative interface framework for Flask
https://flask-admin.readthedocs.io
BSD 3-Clause "New" or "Revised" License
5.8k stars 1.58k forks source link

How to create custom inline field? #1614

Open dodumosu opened 6 years ago

dodumosu commented 6 years ago

My project using Flask-Admin has recently switched database backends from MongoDB with MongoEngine to PostgreSQL with SQLAlchemy. We had a ListField of EmbeddedDocumentFields that rendered individual inline forms for each item. Currently, we're using a plain JSONB field to replace that, but I'd still like to be able to render a dynamic number of forms for each item (since they have a schema).

I initially tried using a WTForms FieldList with a StringField to see if I could then switch to using a FormField, but the resulting (single) text field was not editable. Is there a way I can create individual inline forms for each item in my JSONB field? Thanks in advance.

ljluestc commented 8 months ago
from flask_admin.form import Select2Widget
from flask_admin.model.form import InlineFormField, InlineFieldList
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, FieldList, FormField
from wtforms.validators import DataRequired

# Define your custom form for each item in the JSONB field
class CustomItemForm(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    # Add other fields as needed

# Define a form for the parent object that contains the JSONB field
class ParentForm(FlaskForm):
    # Example field for the JSONB data
    jsonb_data = FieldList(FormField(CustomItemForm))

# Define the Flask-Admin model view
class ParentModelView(ModelView):
    form = ParentForm
    column_editable_list = ['jsonb_data']

    # Override form creation to handle JSONB field rendering
    def scaffold_form(self):
        form_class = self.form
        if self.form_args:
            form_class = self.get_form()
        form_class.jsonb_data = FieldList(FormField(CustomItemForm))
        return form_class

    # Other Flask-Admin configuration for your model view
    # ...