How to add an extra field in the edit form in Flask Admin?
Asked Answered
B

3

5

I want to add a field projects to my User edit form with Flask Admin.

To do so I tried to override the edit_form method to add the field as an additional attribute to the form, but the field is not added.

I cannot find any clear documentation about how to do add a field to the form in Flask Admin.

Anybody can help ?

class UserAdminView(ModelView):
    column_exclude_list = ['password',]    
    form_widget_args = {
        'password':{
            'disabled': True
        }
    }

    def edit_form(self, obj=None):
    form = super(UserAdminView, self).edit_form(obj)

    form.projects = sqla.fields.QuerySelectMultipleField(
        "Projects",
        query_factory=lambda: db.session.query(Project).join(UserProjectRel) \
        .filter(UserProjectRel.user_id==obj.id),
    )

    return form


class User(db.Model):  
    __tablename__ = 'phaunos_user'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    is_admin = db.Column(db.Boolean, default=False, nullable=False)
    confirmed_on = db.Column(db.DateTime, nullable=True)


class UserProjectRel(db.Model):
    __tablename__ = 'user_project_rel'
    user_id = db.Column(db.Integer, db.ForeignKey('phaunos_user.id'), primary_key=True)
    project_id = db.Column(db.Integer, db.ForeignKey('project.id'), primary_key=True)
    user_role = db.Column(ENUM(Role), nullable=False)

    user = db.relationship('User', backref=db.backref('user_project_rel', cascade='all'))
    project = db.relationship('Project', backref=db.backref('user_project_rel', cascade='all'))

enter image description here

Bik answered 6/3, 2019 at 10:43 Comment(0)
B
4

I first had to override get_edit_form:

class UserAdminView(ModelView):
    column_exclude_list = ['password',]
    form_excluded_columns = ['annotations', 'user_project_rel']
    form_widget_args = {
        'password':{
            'disabled': True
        }
    }

    def get_edit_form(self):
        form = super(UserAdminView, self).get_edit_form()
        form.projects = sqla.fields.QuerySelectMultipleField("Projects")
        return form

    def edit_form(self, obj=None):
        form = super(UserAdminView, self).edit_form(obj)
        form.projects.query = db.session.query(Project).join(UserProjectRel) \
            .filter(UserProjectRel.user_id==obj.id).all()
        form.projects.data = form.projects.query
        return form
Bik answered 6/3, 2019 at 15:38 Comment(0)
A
4

I think you missed the form_extra_fields attribute on BaseModelView class, so to add project input:

from wtforms.fields import TextField

class UserAdminView(ModelView):
...
    form_extra_fields = {
        'Projects': TextField('Projects')
    }
Ably answered 8/3, 2019 at 14:37 Comment(1)
This would add a field to both the edit and create form.Bik
N
0

I think you can solve it with form_edit_rules (docs). Documentations focuses only on form_create_rules, but if you want to interact with the edit form only, you can do it with the form_edit_rules property (it accepts a list of form field names and, of course, the newly created field).

Nomo answered 16/10, 2022 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.