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.97k stars 1.61k forks source link

bootstrap4 with form choices #2232

Open SlimBeji opened 3 years ago

SlimBeji commented 3 years ago

Hello,

I am trying to use flask-admin with bootstarp4 template mode.

I have a class user that contains a status field

class User(db.Model):
    id = Column(db.Integer, primary_key=True)
    name = Column(db.UnicodeText)
    email = Column(db.UnicodeText, unique=True, nullable=False)
    status = Column(db.UnicodeText)

In the flask admin panel, I want to restrict the values that can be set for the user.status to "trialing" and "active" for example.

so I have defined the following view

class UserModelView(sqla.ModelView):
    column_editable_list = ["status"]
    form_choices = {
        "status": [("trialing", "trialing"), ("active", "active")]
    }

The Edit view works as expected however trying to edit the field in the List view does not work as expected even though I specified column_editable_list = ["status"]. When checking the logs, I get a weird:

/admin/user/[%7B%22text%22:%20%22%22,%20%22value%22:%20%22__None%22%7D,%20%7B%22text%22:%20%22trialing%22,%20%22value%22:%20%22trialing%22%7D,%20%7B%22text%22:%20%22active%22,%20%22value%22:%20%22active%22%7D]?query=&_=1646044085900 HTTP/1.1" 404 -

after decoding:

/admin/user/[{"text": "", "value": "__None"}, {"text": "trialing", "value": "trialing"}, {"text": "active", "value": "active"}]?query=&_=1646044085900HTTP/1.1"404-

Switching to bootstrap3 does fix the issue and I am able to use the predefined choices in both List and Edit view.

caffeinatedMike commented 3 years ago

This can be resolved if you convert the status column to a proper enum field

class User(db.Model):
    id = Column(db.Integer, primary_key=True)
    name = Column(db.UnicodeText)
    email = Column(db.UnicodeText, unique=True, nullable=False)
    status = Column(db.Enum("trailing", "active"))
SlimBeji commented 3 years ago

@caffeinatedMike Thank you for your answer but we don't really want to put such strong constraint on the DB side. Between downgrading to bootstrap3 or changing the model, we prefer bootstrap3.

Is there a possibility of fixing the bootstrap4 template ?

HossamOkasha commented 2 years ago

Try this:

def on_form_prefill(self, form, id):
    form.status.choices = [("trialing", "trialing"), ("active", "active")]
nonozone commented 9 months ago

I also encountered the same problem. The same code works fine in local testing, but not on the production server.