How can I turn a string model field into a select input in Flask-Admin?
Asked Answered
C

2

7

I have a string field in my SQLAlchemy model and I would like to expose a select box with a few options in Flask-Admin instead of the standard text field.

class MyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    my_field = db.Column(db.String(128))  # Field I would like to be choices


class MyModelView(ModelView):
    """
    Admin manager for MyModel
    """

    # Which option should I use here?

    def __init__(self):
        super(MyModelView, self).__init__(MyModel, db.session)
Cortese answered 26/6, 2015 at 20:21 Comment(0)
T
6

You achieve this functionality by using 'form_choices' in the model view as the following example based on the code embedded in your question illustrates:

   class MyModel(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       my_field = db.Column(db.String(128))  # Field I would like to be choices


    class MyModelView(ModelView):
        """
        Admin manager for MyModel
        """

            form_choices = {
                 'my_field': [
                     ('choice_1', 'Choice 1'),
                     ('choice_2', 'Choice 2'),
                     ('choice_3', 'Choice 3'),
                     ('choice_4', 'Choice 4'),
                     ('choice_5', 'Choice 5')
                ]
           }

        def __init__(self):
            super(MyModelView, self).__init__(MyModel, db.session)

Reference:

Flask-Admin documentation:

You can restrict the possible values for a text-field by specifying a list of select choices:

form_choices = { 'title': [ ('MR', 'Mr'), ('MRS', 'Mrs'), ('MS', 'Ms'), ('DR', 'Dr'), ('PROF', 'Prof.') ] }

Thread answered 13/4, 2017 at 8:35 Comment(0)
C
12

It ended up being a combination of form_overrides and form_args. form_overrides tells the form to use a select field and form_args allows you to pass choices and other options.

class MyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    my_field = db.Column(db.String(128))


class MyModelView(ModelView):
    """
    Admin manager for MyModel
    """

    form_overrides = dict(
        my_field=SelectField
    )
    form_args = dict(
        my_field=dict(
            choices=[
                ('choice_1', 'Choice 1'),
                ('choice_2', 'Choice 2')
            ]
        )
    )
    def __init__(self):
        super(MyModelView, self).__init__(MyModel, db.session)
Cortese answered 26/6, 2015 at 20:37 Comment(1)
For those encountering a UnboundField is not callable exception related to Flask-Admin. It may be because you didn't do what this question suggests, defining solely the field class in form_overrides and then configuring its instance with the form_args entry.Santanasantayana
T
6

You achieve this functionality by using 'form_choices' in the model view as the following example based on the code embedded in your question illustrates:

   class MyModel(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       my_field = db.Column(db.String(128))  # Field I would like to be choices


    class MyModelView(ModelView):
        """
        Admin manager for MyModel
        """

            form_choices = {
                 'my_field': [
                     ('choice_1', 'Choice 1'),
                     ('choice_2', 'Choice 2'),
                     ('choice_3', 'Choice 3'),
                     ('choice_4', 'Choice 4'),
                     ('choice_5', 'Choice 5')
                ]
           }

        def __init__(self):
            super(MyModelView, self).__init__(MyModel, db.session)

Reference:

Flask-Admin documentation:

You can restrict the possible values for a text-field by specifying a list of select choices:

form_choices = { 'title': [ ('MR', 'Mr'), ('MRS', 'Mrs'), ('MS', 'Ms'), ('DR', 'Dr'), ('PROF', 'Prof.') ] }

Thread answered 13/4, 2017 at 8:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.