Flask-Admin aims to be a flexible, customizable web-based interface to your datastore. Currently, Flask-Admin only works with SQLAlchemy declarative models but support for additional datastores will be added in future versions.
Note
Flask-Admin will only work with versions of Flask 0.7 or above.
Create some SQLAlchemy declarative models using SQLAlchemy or Flask-SQLAlchemy:
engine = create_engine('sqlite://', convert_unicode=True)
Base = declarative_base(bind=engine)
class Student(Base):
__tablename__ = 'student'
id = Column(Integer, primary_key=True)
name = Column(String(120), unique=True)
def __repr__(self):
return self.name
class Teacher(Base):
__tablename__ = 'teacher'
id = Column(Integer, primary_key=True)
name = Column(String(120), unique=True)
def __repr__(self):
return self.name
Note
The __repr__ method of your model class will be used to describe specific instances of your models models in things like the list view. If you don’t set it the default __repr__ method will look something like <__main__.Student object at 0x1bb1490>, which won’t be very useful for distinguishing which model instance is which.
Then create a blueprint using those models and your sqlalchemy session:
db_session = scoped_session(sessionmaker(
autocommit=False, autoflush=False,
bind=engine))
admin_blueprint = admin.create_admin_blueprint(
(Student, Teacher), db_session)
The first argument to create_admin_blueprint can have two forms: it can either be some python iterable like a list or tuple, or it can be a python module that contains your models. The second argument is the sqlalchemy session that will be used to access the database. By default, Flask-Admin will not expose the primary keys of your models. This is usually a good idea if you are using a primary key that doesn’t have any meaning outside of the database, like an auto-incrementing integer, because changing a primary key changes the nature of foreign key relationships. If you want to expose primary key, set exclude_pks=False in the create_admin_blueprint call.
Next, register this blueprint on your Flask app:
app = Flask(__name__)
app.register_blueprint(admin_blueprint, url_prefix='/admin')
Now the admin interface is set up. If you are running the app with the built-in development server via app.run(), then it would be available at http://localhost:5000/admin . See the examples directory of the flask-admin source code for some applications that that demonstrate ideas of how to configure the admin.
Your model classes must be able to be initialized without any arguments. For example, this works because the name argument is optional:
class Person(Base):
id = Column(Integer, primary_key=True)
name = Column(String(120), unique=True)
def __init__(self, name=None):
self.name = name
def __repr__(self):
return self.name
But the following will not work because in this latter case, the __init__ method of User() requires a name:
class Person(Base):
id = Column(Integer, primary_key=True)
name = Column(String(120), unique=True)
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
If you want to refer to views in Flask-Admin, the following endpoints are available:
Note
You can use the name argument in create_admin_blueprint() to set the name of the blueprint. For example if name="my_named_admin", then the endpoint for the index becomes 'my_named_admin.index'. This is necessary if you are going to use multiple distinct admin blueprints within the same app.
Using Flask blueprints makes customizing the admin interface really easy. Flask-Admin comes with a default set of templates and static files. You can customize as much of the interface as you’d like by just overriding any files you’d like to change. To do this, just create them in the templates and/or static directories of your app. Refer to the documentation on Flask blueprints for more. There is also an example of this in examples/authentication/view_decorator.py
Flask-Admin uses the WTForms library to automatically generate the form that will be used to add a new instance of a model or edit an existing model instance. There may be cases where the automatically generated form isn’t what you want, so you can also create a custom form for Flask-Admin to use for a given model.
For example, consider the following model of a User that stores hashed passwords:
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(String(80), unique=True)
_password_hash = Column('password', String(80), nullable=False)
is_active = Column(Boolean, default=True)
def __init__(self, username="", password="", is_active=True):
self.username = username
self.password = password
self.is_active = is_active
def check_password(self, password):
return check_password_hash(self.pw_hash, password)
@property
def password(self):
return self._password_hash
@password.setter
def password(self, password):
self._password_hash = generate_password_hash(password)
password = synonym('_password_hash', descriptor=password)
def __repr__(self):
return self.username
To allow this model to be used with a typical password and confirmation field form, you could create the following form:
class UserForm(Form):
"""
Form for creating or editting User object (via the admin). Define
any handling of fields here. This form class also has precedence
when rendering forms to a webpage, so the model-generated fields
will come after it.
"""
username = TextField(u'User name',
[validators.required(),
validators.length(max=80)])
password = PasswordField('Change Password',
[validators.optional(),
validators.equal_to('confirm_password')])
confirm_password = PasswordField()
is_active = BooleanField(default=True)
And just use the model_forms argument when calling create_admin_blueprint to associate this form with the User model:
admin_blueprint = admin.create_admin_blueprint(
(User,), db_session, model_forms={'User': UserForm})
Now the UserForm will be used for editing and adding a new user. If the form passes the validation checks, then password will propagate to the User model and will be hashed and stored the password in the database.
Note
Due to the way that forms are generated, the order of input fields is difficult to control. This is something that is expected to improve in future versions, but for now a custom form is also the only way to specify the order of form fields.
Returns a blueprint that provides the admin interface views. The blueprint that is returned will still need to be registered to your flask app. Additional parameters will be passed to the blueprint constructor.
The parameters are: