SQLAlchemy backend

Flask-Admin comes with SQLAlchemy ORM backend.

Notable features:

  • SQLAlchemy 0.6+ support
  • Paging, sorting, filters
  • Proper model relationship handling
  • Inline editing of related models

Getting Started

In order to use SQLAlchemy model scaffolding, you need to have:

  1. SQLAlchemy ORM model
  2. Initialized database session

If you use Flask-SQLAlchemy, this is how you initialize Flask-Admin and get session from the SQLAlchemy object:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.admin import Admin
from flask.ext.admin.contrib.sqla import ModelView

app = Flask(__name__)
# .. read settings
db = SQLAlchemy(app)

# .. model declarations here

if __name__ == '__main__':
    admin = Admin(app)
    # .. add ModelViews
    # admin.add_view(ModelView(SomeModel, db.session))

Creating simple model

Using previous template, lets create simple model:

# .. flask initialization
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    email = db.Column(db.String(128))

if __name__ == '__main__':
    admin = Admin(app)
    admin.add_view(ModelView(User, db.session))

    db.create_all()
    app.run('0.0.0.0', 8000)

If you will run this example and open http://localhost:8000/, you will see that Flask-Admin generated administrative page for the model:

../_images/sqla_1.png

You can add new models, edit existing, etc.

Customizing administrative interface

List view can be customized in different ways.

First of all, you can use various class-level properties to configure what should be displayed and how. For example, column_list can be used to show some of the column or include extra columns from related models.

For example:

class UserView(ModelView):
    # Show only name and email columns in list view
    column_list = ('name', 'email')

    # Enable search functionality - it will search for terms in
    # name and email fields
    column_searchable_list = ('name', 'email')

    # Add filters for name and email columns
    column_filters = ('name', 'email')

Alternatively, you can override some of the ModelView methods and implement your custom logic.

For example, if you need to contribute additional field to the generated form, you can do something like this:

class UserView(ModelView):
    def scaffold_form(self):
        form_class = super(UserView, self).scaffold_form()
        form_class.extra = TextField('Extra')
        return form_class

Check flask.ext.admin.contrib.sqla documentation for list of configuration properties and methods.

Multiple Primary Keys

Flask-Admin has limited support for models with multiple primary keys. It only covers specific case when all but one primary keys are foreign keys to another model. For example, model inheritance following this convention.

Lets Model a car with its tyres:

class Car(db.Model):
    __tablename__ = 'cars'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    desc = db.Column(db.String(50))

    def __unicode__(self):
        return self.desc

class Tyre(db.Model):
    __tablename__ = 'tyres'
    car_id = db.Column(db.Integer, db.ForeignKey('cars.id'), primary_key=True)
    tyre_id = db.Column(db.Integer, primary_key=True)
    car = db.relationship('Car', backref='tyres')
    desc = db.Column(db.String(50))

A specific tyre is identified by using the two primary key columns of the Tyre class, of which the car_id key is itself a foreign key to the class Car.

To be able to CRUD the Tyre class, you need to enumerate columns when defining the AdminView:

class TyreAdmin(sqla.ModelView):
    form_columns = ['car', 'tyre_id', 'desc']

The form_columns needs to be explicit, as per default only one primary key is displayed.

When having multiple primary keys, no validation for uniqueness prior to saving of the object will be done. Saving a model that violates a unique-constraint leads to an Sqlalchemy-Integrity-Error. In this case, Flask-Admin displays a proper error message and you can change the data in the form. When the application has been started with debug=True the werkzeug debugger will catch the exception and will display the stacktrace.

A standalone script with the Examples from above can be found in the examples directory.

Example

Flask-Admin comes with relatively advanced example, which you can see here.