Flask-Admin¶
Flask-Admin is a batteries-included, simple-to-use Flask extension that lets you add admin interfaces to Flask applications. It is inspired by the django-admin package, but implemented in such a way that the developer has total control of the look, feel and functionality of the resulting application.
Browse through the documentation below to learn more about what you can do with Flask-Admin. Or head over to our GitHub repository to find out how you can contribute to the project.
Quick Start¶
This page gives a quick introduction to the Flask-Admin library. It is assumed that the reader has some prior knowledge of the Flask framework.
If you’re a Django user, you might also find the Migrating from Django guide helpful.
Introduction¶
The library is intended to be as flexible as possible. And the developer should not need to monkey-patch anything to achieve desired functionality.
The library uses one simple, but powerful concept - administrative pieces are built as classes with view methods.
For example, here is an absolutely valid administrative piece:
class MyView(BaseView):
@expose('/')
def index(self):
return self.render('admin/myindex.html')
@expose('/test/')
def test(self):
return self.render('admin/test.html')
If the user visits the index view, the admin/myindex.html template will be rendered. In the same way, visiting the test view will result in the admin/test.html view being rendered.
So, how does this approach help in structuring an admin interface? With such building blocks, you’re implementing reusable functional pieces that are highly customizable.
For example, Flask-Admin provides a ready-to-use SQLAlchemy model interface. It is implemented as a class which accepts two parameters: the model class and a database session. While it exposes some class-level variables which change behavior of the interface (somewhat similar to django.contrib.admin), nothing prohibits you from inheriting from it and overriding the form creation logic, database access methods or extend existing functionality by adding more views.
Initialization¶
To start using Flask-Admin, you have to create a Admin
class instance and associate it
with the Flask
application instance:
from flask import Flask
from flask_admin import Admin
app = Flask(__name__)
admin = Admin(app)
# Add administrative views here
app.run()
If you start this application and navigate to http://localhost:5000/admin/, you should see an empty “Home” page with a navigation bar on top
You can change the application name by passing a value for the name parameter to the
Admin
class constructor:
admin = Admin(app, name='My App')
As an alternative to passing a Flask application object to the Admin constructor, you can also call the
init_app()
function, after the Admin instance has been initialized:
admin = Admin(name='My App')
# Add views here
admin.init_app(app)
Adding views¶
Now, lets add an administrative view. The next example will result in two items appearing in the navbar menu: Home
and Hello. To do this, you need to derive from the BaseView
class:
from flask import Flask
from flask_admin import Admin, BaseView, expose
class MyView(BaseView):
@expose('/')
def index(self):
return self.render('index.html')
app = Flask(__name__)
admin = Admin(app)
admin.add_view(MyView(name='Hello'))
app.run()
One important restriction on admin views is that each view class should have a default page-view method with a root url, ‘/’. The following example is correct:
class MyView(BaseView):
@expose('/')
def index(self):
return self.render('index.html')
but, this wouldn’t work:
class MyView(BaseView):
@expose('/index/')
def index(self):
return self.render('index.html')
Now, create a new index.html file with following content:
{% extends 'admin/master.html' %}
{% block body %}
Hello World from MyView!
{% endblock %}
and place it in a templates directory. To maintain a consistent look and feel, all administrative pages should extend the admin/master.html template.
You should now see your new admin page in action on the Hello page
To add another level of menu items, you can specify a value for the category parameter when passing admin views to the Admin instance. The category specifies the name of the top-level menu item, and all of the views that are associated with it, will be accessible from a drop-down menu. For example:
from flask import Flask
from flask_admin import Admin, BaseView, expose
class MyView(BaseView):
@expose('/')
def index(self):
return self.render('index.html')
app = Flask(__name__)
admin = Admin(app)
admin.add_view(MyView(name='Hello 1', endpoint='test1', category='Test'))
admin.add_view(MyView(name='Hello 2', endpoint='test2', category='Test'))
admin.add_view(MyView(name='Hello 3', endpoint='test3', category='Test'))
app.run()
will look like
Authentication¶
Flask-Admin does not make any assumptions about the authentication system you might be using. So, by default, the admin interface is completely open.
To control access to the admin interface, you can specify an is_accessible method when extending the BaseView class. So, for example, if you are using Flask-Login for authentication, the following will ensure that only logged-in users have access to the view in question:
class MyView(BaseView):
def is_accessible(self):
return login.current_user.is_authenticated()
To redirect the user to another page if authentication fails, you will need to specify an _handle_view method:
class MyView(BaseView):
def is_accessible(self):
return login.current_user.is_authenticated()
def _handle_view(self, name, **kwargs):
if not self.is_accessible():
return redirect(url_for('login', next=request.url))
You can also implement policy-based security, conditionally allowing or disallowing access to parts of the administrative interface. If a user does not have access to a particular view, the menu item won’t be visible.
Model Views¶
Model views allow you to add dedicated admin pages for each of the models in your database. Do this by creating instances of the ModelView class, which you can import from one of Flask-Admin’s built-in ORM backends. An example is the SQLAlchemy backend, which you can use as follows:
from flask_admin.contrib.sqla import ModelView
# Flask and Flask-SQLAlchemy initialization here
admin = Admin(app)
admin.add_view(ModelView(User, db.session))
This creates an admin page for the User model. By default, the list view looks like
To customize these model views, you have two options: Either you can override the public properties of the ModelView class, or you can override its methods.
For example, if you want to disable model creation and only show certain columns in the list view, you can do something like:
from flask_admin.contrib.sqla import ModelView
# Flask and Flask-SQLAlchemy initialization here
class MyView(ModelView):
# Disable model creation
can_create = False
# Override displayed fields
column_list = ('login', 'email')
def __init__(self, session, **kwargs):
# You can pass name and other parameters if you want to
super(MyView, self).__init__(User, session, **kwargs)
admin = Admin(app)
admin.add_view(MyView(db.session))
Overriding form elements can be a bit trickier, but it is still possible. Here’s an example of how to set up a form that includes a column named status that allows only predefined values and therefore should use a SelectField:
from wtforms.fields import SelectField
class MyView(ModelView):
form_overrides = dict(status=SelectField)
form_args = dict(
# Pass the choices to the `SelectField`
status=dict(
choices=[(0, 'waiting'), (1, 'in_progress'), (2, 'finished')]
))
It is relatively easy to add support for different database backends (Mongo, etc) by inheriting from
BaseModelView
.
class and implementing database-related methods.
Please refer to flask_admin.contrib.sqla
documentation on how to customize the behavior of model-based
administrative views.
File Admin¶
Flask-Admin comes with another handy battery - file admin. It gives you the ability to manage files on your server (upload, delete, rename, etc).
Here is simple example:
from flask_admin.contrib.fileadmin import FileAdmin
import os.path as op
# Flask setup here
admin = Admin(app)
path = op.join(op.dirname(__file__), 'static')
admin.add_view(FileAdmin(path, '/static/', name='Static Files'))
Sample screenshot:
You can disable uploads, disable file or directory deletion, restrict file uploads to certain types and so on.
Check flask_admin.contrib.fileadmin
documentation on how to do it.
Generating URLs¶
Internally, view classes work on top of Flask blueprints, so you can use url_for with a dot prefix to get the URL for a local view:
from flask import url_for
class MyView(BaseView):
@expose('/')
def index(self)
# Get URL for the test view method
url = url_for('.test')
return self.render('index.html', url=url)
@expose('/test/')
def test(self):
return self.render('test.html')
If you want to generate a URL for a particular view method from outside, the following rules apply:
You can override the endpoint name by passing endpoint parameter to the view class constructor:
admin = Admin(app) admin.add_view(MyView(endpoint='testadmin'))
In this case, you can generate links by concatenating the view method name with an endpoint:
url_for('testadmin.index')
If you don’t override the endpoint name, the lower-case class name can be used for generating URLs, like in:
url_for('myview.index')
For model-based views the rules differ - the model class name should be used if an endpoint name is not provided. The ModelView also has these endpoints by default: .index_view, .create_view, and .edit_view. So, the following urls can be generated for a model named “User”:
# List View url_for('user.index_view') # Create View (redirect back to index_view) url_for('user.create_view', url=url_for('user.index_view')) # Edit View for record #1 (redirect back to index_view) url_for('user.edit_view', id=1, url=url_for('user.index_view'))
Examples¶
Flask-Admin comes with several examples, that will really help you get a grip on what’s possible. Browse through them in the GitHub repo, and then run them locally to get yourself up to speed in no time:
- Simple views
Here we show how to add some simple custom views to your admin interface. They don’t have to be associated to any of your database models. You can fill them with whatever content you want.
- Custom layout
Override some of the built-in templates to get complete control over the look and feel of your Admin interface. Either while using the default Bootstrap 2, or the newer Bootstrap 3.
- SQLAlchemy model example
Model-based views provide heaps of builtin goodness, making it really easy to get a set of the default CRUD views in place. This example shows some of the basics.
- SQLAlchemy model views with custom forms and file handling
Here, we show some of the more interesting things you can do with very little effort, including customizing the builtin forms, and adding support for handling file/image uploads.
- Flask-Login integration example
Use Flask-Login for authentication to hide some of your admin views behind a login wall.
- Peewee model example
Not so keen on SQLAlchemy? Perhaps you’d rather use Peewee?
- MongoEngine model example
... or check this example if MongoDB is more your style.
- I18n and L10n with Flask-BabelEx
Do you need to make your Admin interface available in other languages? Luckily, Flask-Admin is built for just that kind of thing.
- Redis terminal
If you use Redis for caching, then check this example to see how easy it is to add a Redis terminal to your Admin interface, so you can reach your Redis instance straight from a browser.
Migrating from Django¶
If you are used to Django and the django-admin package, you will find Flask-Admin to work slightly different from what you would expect.
This guide will help you to get acquainted with the Flask-Admin library. It is assumed that you have some prior knowledge of Flask .
Design Philosophy¶
In general, Django and django-admin strives to make life easier by implementing sensible defaults. So a developer will be able to get an application up in no time, but it will have to conform to most of the defaults. Of course it is possible to customize things, but this often requires a good understanding of what’s going on behind the scenes, and it can be rather tricky and time-consuming.
The design philosophy behind Flask is slightly different. It embraces the diversity that one tends to find in web applications by not forcing design decisions onto the developer. Rather than making it very easy to build an application that almost solves your whole problem, and then letting you figure out the last bit, Flask aims to make it possible for you to build the whole application. It might take a little more effort to get started, but once you’ve got the hang of it, the sky is the limit... Even when your application is a little different from most other applications out there on the web.
Flask-Admin follows this same design philosophy. So even though it provides you with several tools for getting up & running quickly, it will be up to you, as a developer, to tell Flask-Admin what should be displayed and how. Even though it is easy to get started with a simple CRUD interface for each model in your application, Flask-Admin doesn’t fix you to this approach, and you are free to define other ways of interacting with some, or all, of your models.
Due to Flask-Admin supporting more than one ORM (SQLAlchemy, MongoEngine, Peewee, raw pymongo), the developer is even free to mix different model types into one application by instantiating appropriate CRUD classes.
Getting started¶
At the basis of Flask-Admin is the idea that you can add components to your admin interface by declaring a separate class for each component, and then adding a method to that class for every view that should be associated to the component. Since classes can inherit from one another, and since several instances of the same class can be created, this approach allows for a great deal of flexibility.
Let’s write a bit of code to create a simple CRUD interface for the Post SQLAlchemy model. The example below uses the Flask-SQLAlchemy extension, but you don’t have to use it (you could also use the SQLAlchemy declarative extension):
from flask import Flask
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.Unicode(120))
text = db.Column(db.UnicodeText, nullable=False)
admin = Admin(app)
admin.add_view(ModelView(Post, db.session))
To customize the behavior of the model’s CRUD interface, you can set values for some of the special properties (as listed below) that are made available through model.BaseModelView, or one of the ORM wrappers:
# ... imports
class PostView(ModelView):
list_columns = ('title',)
def __init__(self):
super(PostView, self).__init__(Post, db.session)
# ... initialization
admin.add_view(PostView())
Because each component is implemented as a class, you can also customize it in the constructor:
class PostView(ModelView):
list_columns = ('title',)
def __init__(self, include_id=False):
if include_id:
self.list_columns = ('id', 'title')
super(PostView, self).__init__(Post, db.session)
Here is a list of some of the configuration properties that are made available by Flask-Admin and the SQLAlchemy backend. You can also see which django-admin properties they correspond to:
Django | Flask-Admin |
---|---|
actions | flask_admin.actions |
exclude | form_excluded_columns |
fields | form_columns |
form | form |
formfield_overrides | form_args |
inlines | inline_models |
list_display | column_list |
list_filter | column_filters |
list_per_page | page_size |
search_fields | column_searchable_list |
add_form_template | create_template |
change_form_template | change_form_template |
You might want to check flask_admin.model for basic model configuration options (reused by all model backends) and specific backend documentation, for example flask_admin.contrib.sqla. There’s much more than what is displayed in this table.
Authentication¶
To restrict access to your admin interface, you can implement your own class for creating admin components, and override the is_accessible method:
class MyModelView(ModelView):
def is_accessible(self):
return login.current_user.is_authenticated()
Components that are not accessible to a particular user, will also not be displayed in the menu for that user.
Templates¶
Flask-Admin uses Jinja2 templating engine. Jinja2 is pretty advanced templating engine and Flask-Admin templates were made to be easily extensible.
For example, if you need to include a javascript snippet on the Edit page for one of your models, you could:
{% extends 'admin/model/edit.html' %}
{% block tail %}
{{ super() }}
<script language="javascript">alert('Hello World!')</script>
{% endblock %}
and then point your class to this new template:
class MyModelView(ModelView):
edit_template = 'my_edit_template.html'
For list of available template blocks, check Working with templates.
Tips and hints¶
- Programming with Flask-Admin is not very different from normal application development - write some views and expose them to the user, using templates to create a consistent user experience.
- If you are missing some functionality which can be used more than once, you can create your own “base” class and use it instead of default implementation.
- Using Jinja2, you can easily extend the existing templates. You can even change the look and feel of the admin interface completely, if you want to. Check this example.
- You are not limited to a simple CRUD interface for every model. Want to add some kind of realtime monitoring via websockets? No problem.
- There’s a so called “index view”. By default it is empty, but you can put any information you need there. It is displayed under the Home menu option.
Working with templates¶
One great advantage of building an extension on top of Flask, is the great templating engine that comes with the package. Jinja2 allows you to use most of the Python syntax that you are used to, inside of your templates, helping you generate either text or code in a powerful, yet flexible way.
To explore some more of what Jinja2 can offer you, head over to their documentation at http://jinja.pocoo.org/docs/. But the most important features for you to understand in order to get started with Flask-Admin are given below.
Inheritance¶
Templates can extend other templates. This enables you, for example, to build the standard components of your site into a base template, where they are defined only once. This template can then be extended by other templates, where more specific content may be added.
Large applications may end up having several layers of templates, starting for example with a very general HTML structure, and then growing more and more specific at each level, until the final layer of templates define unique pages in the application. But it needs not be very complicated, and the majority of applications will only really need a handful of well-designed templates.
Building blocks¶
With Jinja2, templates are made up of blocks of code, which define where a child template’s contents fit into the bigger picture, as defined by the parent template.
A parent template may define any number of these code blocks, and a child template may define content for any number of those. So, by extending an existing template, you get to just fill-in the blanks, rather than having to deal with lots of boilerplate code that is not really relevant to the problem at hand.
Power & Flexibility¶
When a block is defined in a parent template, it can already be given some content, ensuring that something will be rendered in that place, even if a child template chooses to ignore that block completely.
If content is defined in a child template, you have the option of also rendering the code that the parent template may have defined in that block by calling:
{{ super() }}
anywhere inside that block. But the default behaviour is to simply override the block entirely.
Since these template blocks are defined by name, you have a lot of freedom in how you decide to arrange / nest them in your code.
Jinja2 & Flask Admin¶
Flask-Admin defines one base template at admin/master.html that all the other admin templates are derived from. This template is a proxy which points to admin/base.html, which defines the following blocks:
Block Name | Description |
---|---|
head_meta | Page metadata in the header |
title | Page title |
head_css | Various CSS includes in the header |
head | Empty block in HTML head, in case you want to put something there |
page_body | Page layout |
brand | Logo in the menu bar |
main_menu | Main menu |
menu_links | Links menu |
access_control | Section to the right of the menu (can be used to add login/logout buttons) |
messages | Alerts and various messages |
body | Content (that’s where your view will be displayed) |
tail | Empty area below content |
Adding an Index Page¶
You’ll notice that the ‘Home’ page that is created by Flask-Admin at /admin is largely empty. By default, the only content on the page is a set of controls for navigating to the views that you have defined. You can change this by creating a template at admin/index.html in your templates directory.
Working with your Models¶
By default, Flask-Admin uses three pre-defined templates for displaying your models in the admin-interface:
- admin/model/list.html
- admin/model/create.html
- admin/model/edit.html
All three of these extend the admin/master.html template, and you can override them by defining your own templates, with the same path relative to your templates folder.
You could also choose to extend these templates, rather than overriding them. In this case you will need to point your classes at your own templates, rather than letting them use the defaults. For example, your own template for the edit views could be defined in templates/my_edit_template.html to look something like:
{% extends 'admin/model/edit.html' %}
{% block tail %}
{{ super() }}
...
{% endblock %}
And your classes could be made to use this template by setting the appropriate class property:
class MyModelView(ModelView):
edit_template = 'my_edit_template.html'
The three available properties are simply called list_template, create_template and edit_template.
Environment variables¶
While working in any of the templates that extend admin/master.html, you have access to a small number of environment variables:
Variable Name | Description |
---|---|
admin_view | Current administrative view |
admin_base_template | Base template name |
_gettext | Babel gettext |
_ngettext | Babel ngettext |
h | Helpers from helpers module |
Customizing templates¶
As noted earlier, you can override any default Flask-Admin template by creating your own template with same name and relative path inside your own templates directory.
You can also override the master template, but then you need to pass your own template name to the Admin constructor:
admin = Admin(app, base_template='my_master.html')
In addition to all of the blocks that are inherited from admin/master.html, the admin/model/list.html template also contains the following blocks:
Block Name | Description |
---|---|
model_menu_bar | Menu bar |
model_list_table | Table container |
list_header | Table header row |
list_row_actions_header | Actions header |
list_row | Single row |
list_row_actions | Row action cell with edit/remove/etc buttons |
empty_list_message | Message that will be displayed if there are no models found |
Localization¶
Flask-Admin makes it possible for you to serve your application in more than one language. To do this, it makes use of the Flask-BabelEx package for handling translations. This package is a fork of the popular Flask-Babel package, with the following features:
- It is API-compatible with Flask-Babel
- It allows distribution of translations with Flask extensions
- It aims to be more configurable than Flask-Babel
Currently Flask-BabelEx is the only supported way of enabling localization support in Flask-Admin.
How to enable localization¶
Install Flask-BabelEx:
pip install flask-babelex
Initialize Flask-BabelEx by creating instance of Babel class:
from flask import app from flask_babelex import Babel app = Flask(__name__) babel = Babel(app)
Create a locale selector function:
@babel.localeselector def get_locale(): # Put your logic here. Application can store locale in # user profile, cookie, session, etc. return 'en'
Initialize Flask-Admin as usual.
You can check the babel example to see localization in action. When running this example, you can change the locale simply by adding a query parameter, like ?en=<locale name> to the URL. For example, a French version of the application should be accessible at: http://localhost:5000/admin/userview/?lang=fr.
Usage Tips¶
General tips¶
A reasonably obvious, but very useful, pattern is to wrap any shared functionality that your different admin views might need into a base class that they can all inherit from (to help you keep things DRY).
For example, rather than manually checking user permissions in each of your admin views, you can implement a base class such as
class MyView(BaseView): def is_accessible(self): return login.current_user.is_authenticated()and every view that inherits from this, will have the permission checking done automatically. The important thing to notice, is that your base class needs to inherit from a built-in Flask-Admin view.
You can override a default template either by passing the path to your own template in to the relevant ModelView property (either list_template, create_template or edit_template) or by putting your own customized version of a default template into your templates/admin/ directory.
To customize the overall look and feel of the default model forms, you have two options: Either, you could override the default create/edit templates. Or, alternatively, you could make use of the form rendering rules (
flask_admin.form.rules
) that were introduced in version 1.0.7.To simplify the management of file uploads, Flask-Admin comes with a dedicated tool, for which you can find documentation at:
flask_admin.form.upload
.If you don’t want to the use the built-in Flask-Admin form scaffolding logic, you are free to roll your own by simply overriding
scaffold_form()
. For example, if you use WTForms-Alchemy, you could put your form generation code into a scaffold_form method in your ModelView class.
SQLAlchemy¶
If the synonym_property does not return a SQLAlchemy field, then Flask-Admin won’t be able to figure out what to do with it, so it won’t generate a form field. In this case, you would need to manually contribute your own field:
class MyView(ModelView): def scaffold_form(self): form_class = super(UserView, self).scaffold_form() form_class.extra = TextField('Extra') return form_class
MongoEngine¶
- Flask-Admin supports GridFS-backed image- and file uploads, done through WTForms fields. Documentation can be found
at
flask_admin.contrib.mongoengine.fields
.
Database backends¶
The purpose of Flask-Admin is to help you manage your data. For this, it needs some database backend in order to be able to access that data in the first place. At present, there are five different backends for you to choose from, depending on which database you would like to use for your application.
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:
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_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_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:
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_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.
GeoAlchemy backend¶
If you want to store spatial information in a GIS database, Flask-Admin has you covered. The GeoAlchemy backend extends the SQLAlchemy backend (just as GeoAlchemy extends SQLAlchemy) to give you a pretty and functional map-based editor for your admin pages.
Notable features:
- Uses the amazing Leaflet Javascript library for displaying maps, with map data from Mapbox
- Uses Leaflet.Draw for editing geographic information interactively, including points, lines, and polygons
- Graceful fallback to editing GeoJSON data in a
<textarea>
, if the user has turned off Javascript- Works with a Geometry SQL field that is integrated with Shapely objects
Getting Started¶
GeoAlchemy is based on SQLAlchemy, so you’ll need to complete the “getting started” directions for SQLAlchemy backend first. For GeoAlchemy, you’ll also need a map ID from Mapbox, a map tile provider. (Don’t worry, their basic plan is free, and works quite well.) Then, just include the map ID in your application settings:
app = Flask(__name__)
app.config['MAPBOX_MAP_ID'] = "example.abc123"
To use the v4 of their API (the default is v3)::
app.config['MAPBOX_ACCESS_TOKEN'] = "pk.def456"
Note
Leaflet supports loading map tiles from any arbitrary map tile provider, but at the moment, Flask-Admin only supports Mapbox. If you want to use other providers, make a pull request!
Creating simple model¶
GeoAlchemy comes with a Geometry field that is carefully divorced from the
Shapely library. Flask-Admin will use this field so that there are no
changes necessary to other code. ModelView
should be imported from
geoa
rather than the one imported from sqla
:
from geoalchemy2 import Geometry
from flask_admin.contrib.geoa import ModelView
# .. flask initialization
db = SQLAlchemy(app)
class Location(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
point = db.Column(Geometry("POINT"))
if __name__ == '__main__':
admin = Admin(app)
admin.add_view(ModelView(User, db.session))
db.create_all()
app.run('0.0.0.0', 8000)
Limitations¶
There’s currently no way to sort, filter, or search on geometric fields in the admin. It’s not clear that there’s a good way to do so. If you have any ideas or suggestions, make a pull request!
MongoEngine backend¶
Features:
- MongoEngine 0.7+ support
- Paging, sorting, filters, etc
- Supports complex document structure (lists, subdocuments and so on)
- GridFS support for file and image uploads
In order to use MongoEngine integration, you need to install the flask-mongoengine package, as Flask-Admin uses form scaffolding from it.
You don’t have to use Flask-MongoEngine in your project - Flask-Admin will work with “raw” MongoEngine models without any problems.
Known issues:
- Search functionality can’t split query into multiple terms due to MongoEngine query language limitations
For more documentation, check flask_admin.contrib.mongoengine documentation.
MongoEngine integration example is here.
Peewee backend¶
Features:
- Peewee 2.x+ support;
- Paging, sorting, filters, etc;
- Inline editing of related models;
In order to use peewee integration, you need to install two additional Python packages: peewee and wtf-peewee.
Known issues:
- Many-to-Many model relations are not supported: there’s no built-in way to express M2M relation in Peewee
For more documentation, check flask_admin.contrib.peewee documentation.
Peewee example is here.
PyMongo backend¶
Pretty simple PyMongo backend.
Flask-Admin does not make assumptions about document structure, so you will have to configure ModelView to do what you need it to do.
This is bare minimum you have to provide for Flask-Admin view to work with PyMongo:
- Provide list of columns by setting column_list property
- Provide form to use by setting form property
- When instantiating
flask_admin.contrib.pymongo.ModelView
class, you have to provide PyMongo collection object
This is minimal PyMongo view:
class UserForm(Form):
name = TextField('Name')
email = TextField('Email')
class UserView(ModelView):
column_list = ('name', 'email')
form = UserForm
if __name__ == '__main__':
admin = Admin(app)
# 'db' is PyMongo database object
admin.add_view(UserView(db['users']))
On top of that you can add sortable columns, filters, text search, etc.
For more documentation, check flask_admin.contrib.pymongo documentation.
PyMongo integration example is here.
If you don’t know where to start, but you’re familiar with relational databases, then you should probably look at using SQLAlchemy. It is a full-featured toolkit, with support for SQLite, PostgreSQL, MySQL, Oracle and MS-SQL amongst others. It really comes into its own once you have lots of data, and a fair amount of relations between your data models. If you want to track spatial data like latitude/longitude points, you should look into GeoAlchemy, as well.
If you’re looking for something simpler, or your data models are reasonably self-contained, then MongoEngine could be a better option. It is a python wrapper around the popular NoSQL database called MongoDB.
Of course, if you feel that there’s an awesome database wrapper that is missing from the list above, we’d greatly appreciate it if you could write the plugin for it and submit it as a pull request. A special section of these docs are dedicated to helping you through this process. See Adding a new model backend.
Adding a new model backend¶
Flask-Admin makes a few assumptions about the database models that it works with. If you want to implement your own database backend, and still have Flask-Admin’s model views work as expected, then you should take note of the following:
- Each model must have one field which acts as a primary key to uniquely identify instances of that model. However, there are no restriction on the data type or the field name of the primary key field.
- Models must make their data accessible as python properties.
If that is the case, then you can implement your own database backend by extending the BaseModelView class, and implementing the set of scaffolding methods listed below.
Extending BaseModelView¶
Start off by defining a new class, which derives from from
BaseModelView
:class MyDbModel(BaseModelView): passThis class inherits BaseModelView’s __init__ method, which accepts a model class as first argument. The model class is stored as the attribute
self.model
so that other methods may access it.Now, implement the following scaffolding methods for the new class:
This method returns a primary key value from the model instance. In the SQLAlchemy backend, it gets the primary key from the model using
scaffold_pk()
, caches it and then returns the value from the model whenever requested.For example:
class MyDbModel(BaseModelView): def get_pk_value(self, model): return self.model.idReturns a list of columns to be displayed in a list view. For example:
class MyDbModel(BaseModelView): def scaffold_list_columns(self): columns = [] for p in dir(self.model): attr = getattr(self.model) if isinstance(attr, MyDbColumn): columns.append(p) return columnsReturns a dictionary of sortable columns. The keys in the dictionary should correspond to the model’s field names. The values should be those variables that will be used for sorting.
For example, in the SQLAlchemy backend it is possible to sort by a foreign key field. So, if there is a field named user, which is a foreign key for the Users table, and the Users table also has a name field, then the key will be user and value will be Users.name.
If your backend does not support sorting, return None or an empty dictionary.
Initialize search functionality. If your backend supports full-text search, do initializations and return True. If your backend does not support full-text search, return False.
For example, SQLAlchemy backend reads value of the self.searchable_columns and verifies if all fields are of text type, if they’re local to the current model (if not, it will add a join, etc) and caches this information for future use.
Generate WTForms form class from the model.
For example:
class MyDbModel(BaseModelView): def scaffold_form(self): class MyForm(Form): pass # Do something return MyFormThis method should return list of model instances with paging, sorting, etc applied.
For SQLAlchemy backend it looks like:
If search was enabled and provided search value is not empty, generate LIKE statements for each field from self.searchable_columns
If filter values were passed, call apply method with values:
for flt, value in filters: query = self._filters[flt].apply(query, value)Execute query to get total number of rows in the database (count)
If sort_column was passed, will do something like (with some extra FK logic which is omitted in this example):
if sort_desc: query = query.order_by(desc(sort_field)) else: query = query.order_by(sort_field)Apply paging
Return count, list as a tuple
Return a model instance by its primary key.
Create a new instance of the model from the Form object.
Update the model instance with data from the form.
Delete the specified model instance from the data store.
Verify whether the given object is a valid filter.
Return a list of filter objects for one model field.
This method will be called once for each entry in the self.column_filters setting.
If your backend does not know how to generate filters for the provided field, it should return None.
For example:
class MyDbModel(BaseModelView): def scaffold_filters(self, name): attr = getattr(self.model, name) if isinstance(attr, MyDbTextField): return [MyEqualFilter(name, name)]
Implementing filters¶
Each model backend should have its own set of filter implementations. It is not possible to use the filters from SQLAlchemy models in a non-SQLAlchemy backend. This also means that different backends might have different set of available filters.
The filter is a class derived from
BaseFilter
which implements at least two methods:
apply()
operation()
apply method accepts two parameters: query object and a value from the client. Here you can add filtering logic for the filter type.
Lets take SQLAlchemy model backend as an example:
All SQLAlchemy filters derive from
BaseSQLAFilter
class.Each filter implements one simple filter SQL operation (like, not like, greater, etc) and accepts a column as input parameter.
Whenever model view wants to apply a filter to a query object, it will call apply method in a filter class with a query and value. Filter will then apply real filter operation.
For example:
class MyBaseFilter(BaseFilter): def __init__(self, column, name, options=None, data_type=None): super(MyBaseFilter, self).__init__(name, options, data_type) self.column = column class MyEqualFilter(MyBaseFilter): def apply(self, query, value): return query.filter(self.column == value) def operation(self): return gettext('equals') # You can validate values. If value is not valid, # return `False`, so filter will be ignored. def validate(self, value): return True # You can "clean" values before they will be # passed to the your data access layer def clean(self, value): return value
Feel free ask questions if you have problems adding a new model backend. Also, if you get stuck, try taking a look at the SQLAlchemy model backend and use it as a reference.
Form rendering rules¶
Before version 1.0.7, all model backends were rendering the create and edit forms using a special Jinja2 macro, which was looping over the fields of a WTForms form object and displaying them one by one. This works well, but it is difficult to customize.
Starting from version 1.0.7, Flask-Admin supports form rendering rules, to give you fine grained control of how the forms for your modules should be displayed.
The basic idea is pretty simple: the customizable rendering rules replace a static macro, so that you can tell Flask-Admin how each form should be rendered. As an extension, however, the rendering rules also let you do a bit more: You can use them to output HTML, call Jinja2 macros, render fields and so on.
Essentially, form rendering rules abstract the rendering, so that it becomes separate from the form definition. So, for example, it no longer matters in which sequence your form fields are defined.
Getting started¶
To start using the form rendering rules, put a list of form field names into the form_create_rules property one of your admin views:
class RuleView(sqla.ModelView):
form_create_rules = ('email', 'first_name', 'last_name')
In this example, only three fields will be rendered and email field will be above other two fields.
Whenever Flask-Admin sees a string value in form_create_rules, it automatically assumes that it is a
form field reference and creates a flask_admin.form.rules.Field
class instance for that field.
Lets say we want to display some text between the email and first_name fields. This can be accomplished by
using the flask_admin.form.rules.Text
class:
from flask_admin.form import rules
class RuleView(sqla.ModelView):
form_create_rules = ('email', rules.Text('Foobar'), 'first_name', 'last_name')
Built-in rules¶
Flask-Admin comes with few built-in rules that can be found in the flask_admin.form.rules
module:
Form Rendering Rule | Description |
---|---|
flask_admin.form.rules.BaseRule |
All rules derive from this class |
flask_admin.form.rules.NestedRule |
Allows rule nesting, useful for HTML containers |
flask_admin.form.rules.Text |
Simple text rendering rule |
flask_admin.form.rules.HTML |
Same as Text rule, but does not escape the text |
flask_admin.form.rules.Macro |
Calls macro from current Jinja2 context |
flask_admin.form.rules.Container |
Wraps child rules into container rendered by macro |
flask_admin.form.rules.Field |
Renders single form field |
flask_admin.form.rules.Header |
Renders form header |
flask_admin.form.rules.FieldSet |
Renders form header and child rules |
Enabling CSRF Validation¶
Adding CSRF validation will require overriding the flask_admin.form.BaseForm
by using flask_admin.model.BaseModelView.form_base_class
.
WTForms >=2:
from wtforms.csrf.session import SessionCSRF
from wtforms.meta import DefaultMeta
from flask import session
from datetime import timedelta
from flask_admin import form
from flask_admin.contrib import sqla
class SecureForm(form.BaseForm):
class Meta(DefaultMeta):
csrf = True
csrf_class = SessionCSRF
csrf_secret = b'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym'
csrf_time_limit = timedelta(minutes=20)
@property
def csrf_context(self):
return session
class ModelAdmin(sqla.ModelView):
form_base_class = SecureForm
For WTForms 1, you can use use Flask-WTF’s Form class:
import os
import flask
import flask_wtf
import flask_admin
import flask_sqlalchemy
from flask_admin.contrib.sqla import ModelView
DBFILE = 'app.db'
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = 'Dnit7qz7mfcP0YuelDrF8vLFvk0snhwP'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + DBFILE
app.config['CSRF_ENABLED'] = True
flask_wtf.CsrfProtect(app)
db = flask_sqlalchemy.SQLAlchemy(app)
admin = flask_admin.Admin(app, name='Admin')
class MyModelView(ModelView):
# Here is the fix:
form_base_class = flask_wtf.Form
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
if not os.path.exists(DBFILE):
db.create_all()
admin.add_view( MyModelView(User, db.session, name='User') )
app.run(debug=True)
Further reading¶
For additional documentation, check flask_admin.form.rules
module source code (it is quite short) and
look at the forms example on GitHub.
API¶
flask_admin.base
¶
Base View¶
-
expose
(url='/', methods=('GET', ))[source]¶ Use this decorator to expose views in your view classes.
Parameters: - url – Relative URL for the view
- methods – Allowed HTTP methods. By default only GET is allowed.
-
expose_plugview
(url='/')[source]¶ Decorator to expose Flask’s pluggable view classes (
flask.views.View
orflask.views.MethodView
).Parameters: url – Relative URL for the view New in version 1.0.4.
-
class
BaseView
(name=None, category=None, endpoint=None, url=None, static_folder=None, static_url_path=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ Base administrative view.
Derive from this class to implement your administrative interface piece. For example:
from flask_admin import BaseView, expose class MyView(BaseView): @expose('/') def index(self): return 'Hello World!'
Icons can be added to the menu by using menu_icon_type and menu_icon_value. For example:
admin.add_view(MyView(name='My View', menu_icon_type='glyph', menu_icon_value='glyphicon-home'))
-
get_url
(endpoint, **kwargs)[source]¶ Generate URL for the endpoint. If you want to customize URL generation logic (persist some query string argument, for example), this is right place to do it.
Parameters: - endpoint – Flask endpoint name
- kwargs – Arguments for url_for
-
inaccessible_callback
(name, **kwargs)[source]¶ Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to customize the behaviour.
-
is_accessible
()[source]¶ Override this method to add permission checks.
Flask-Admin does not make any assumptions about the authentication system used in your application, so it is up to you to implement it.
By default, it will allow access for everyone.
-
Default view¶
-
class
AdminIndexView
(name=None, category=None, endpoint=None, url=None, template='admin/index.html', menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ Default administrative interface index page when visiting the
/admin/
URL.It can be overridden by passing your own view class to the
Admin
constructor:class MyHomeView(AdminIndexView): @expose('/') def index(self): arg1 = 'Hello' return self.render('admin/myhome.html', arg1=arg1) admin = Admin(index_view=MyHomeView())
Also, you can change the root url from /admin to / with the following:
admin = Admin( app, index_view=AdminIndexView( name='Home', template='admin/myhome.html', url='/' ) )
Default values for the index page are:
- If a name is not provided, ‘Home’ will be used.
- If an endpoint is not provided, will default to
admin
- Default URL route is
/admin
. - Automatically associates with static folder.
- Default template is
admin/index.html
Admin¶
-
class
Admin
(app=None, name=None, url=None, subdomain=None, index_view=None, translations_path=None, endpoint=None, static_url_path=None, base_template=None, template_mode=None)[source]¶ Collection of the admin views. Also manages menu structure.
-
init_app
(app)[source]¶ Register all views with the Flask application.
Parameters: app – Flask application instance
Return the menu hierarchy.
Return menu links.
-
flask_admin.helpers
¶
Forms
-
is_required_form_field
(field)[source]¶ Check if form field has DataRequired or InputRequired validators.
Parameters: field – WTForms field to check
-
validate_form_on_submit
(form)[source]¶ If current method is PUT or POST, validate form and return validation status.
-
get_form_data
()[source]¶ If current method is PUT or POST, return concatenated request.form with request.files or None otherwise.
-
is_field_error
(errors)[source]¶ Check if wtforms field has error without checking its children.
Parameters: errors – Errors list.
Jinja2 helpers
flask_admin.model
¶
-
class
BaseModelView
(model, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ Base model view.
This view does not make any assumptions on how models are stored or managed, but expects the following:
- The provided model is an object
- The model contains properties
- Each model contains an attribute which uniquely identifies it (i.e. a primary key for a database model)
- It is possible to retrieve a list of sorted models with pagination applied from a data source
- You can get one model by its identifier from the data source
Essentially, if you want to support a new data store, all you have to do is:
- Derive from the BaseModelView class
- Implement various data-related methods (get_list, get_one, create_model, etc)
- Implement automatic form generation from the model representation (scaffold_form)
-
can_create
= True¶ Is model creation allowed
-
can_edit
= True¶ Is model editing allowed
-
can_delete
= True¶ Is model deletion allowed
-
list_template
= 'admin/model/list.html'¶ Default list view template
-
edit_template
= 'admin/model/edit.html'¶ Default edit template
-
create_template
= 'admin/model/create.html'¶ Default create template
-
column_list
¶ Collection of the model field names for the list view. If set to None, will get them from the model.
For example:
class MyModelView(BaseModelView): column_list = ('name', 'last_name', 'email')
-
column_exclude_list
¶ Collection of excluded list column names.
For example:
class MyModelView(BaseModelView): column_exclude_list = ('last_name', 'email')
-
column_labels
¶ Dictionary where key is column name and value is string to display.
For example:
class MyModelView(BaseModelView): column_labels = dict(name='Name', last_name='Last Name')
-
column_descriptions
= None¶ Dictionary where key is column name and value is description for list view column or add/edit form field.
For example:
class MyModelView(BaseModelView): column_descriptions = dict( full_name='First and Last name' )
-
column_formatters
¶ Dictionary of list view column formatters.
For example, if you want to show price multiplied by two, you can do something like this:
class MyModelView(BaseModelView): column_formatters = dict(price=lambda v, c, m, p: m.price*2)
or using Jinja2 macro in template:
from flask_admin.model.template import macro class MyModelView(BaseModelView): column_formatters = dict(price=macro('render_price')) # in template {% macro render_price(model, column) %} {{ model.price * 2 }} {% endmacro %}
The Callback function has the prototype:
def formatter(view, context, model, name): # `view` is current administrative view # `context` is instance of jinja2.runtime.Context # `model` is model instance # `name` is property name pass
-
column_type_formatters
¶ Dictionary of value type formatters to be used in the list view.
By default, two types are formatted: 1.
None
will be displayed as an empty string 2.bool
will be displayed as a checkmark if it isTrue
If you don’t like the default behavior and don’t want any type formatters applied, just override this property with an empty dictionary:
class MyModelView(BaseModelView): column_type_formatters = dict()
If you want to display NULL instead of an empty string, you can do something like this:
from flask_admin.model import typefmt MY_DEFAULT_FORMATTERS = dict(typefmt.BASE_FORMATTERS) MY_DEFAULT_FORMATTERS.update({ type(None): typefmt.null_formatter }) class MyModelView(BaseModelView): column_type_formatters = MY_DEFAULT_FORMATTERS
Type formatters have lower priority than list column formatters.
The callback function has following prototype:
def type_formatter(view, value): # `view` is current administrative view # `value` value to format pass
-
column_display_pk
¶ Controls if the primary key should be displayed in the list view.
-
column_sortable_list
¶ Collection of the sortable columns for the list view. If set to None, will get them from the model.
For example:
class MyModelView(BaseModelView): column_sortable_list = ('name', 'last_name')
If you want to explicitly specify field/column to be used while sorting, you can use a tuple:
class MyModelView(BaseModelView): column_sortable_list = ('name', ('user', 'user.username'))
When using SQLAlchemy models, model attributes can be used instead of strings:
class MyModelView(BaseModelView): column_sortable_list = ('name', ('user', User.username))
-
column_searchable_list
¶ A collection of the searchable columns. It is assumed that only text-only fields are searchable, but it is up to the model implementation to decide.
Example:
class MyModelView(BaseModelView): column_searchable_list = ('name', 'email')
-
column_default_sort
= None¶ Default sort column if no sorting is applied.
Example:
class MyModelView(BaseModelView): column_default_sort = 'user'
You can use tuple to control ascending descending order. In following example, items will be sorted in descending order:
class MyModelView(BaseModelView): column_default_sort = ('user', True)
-
column_choices
= None¶ Map choices to columns in list view
Example:
class MyModelView(BaseModelView): column_choices = { 'my_column': [ ('db_value', 'display_value'), ] }
-
column_filters
= None¶ Collection of the column filters.
Can contain either field names or instances of
BaseFilter
classes.Example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
-
form
= None¶ Form class. Override if you want to use custom form for your model. Will completely disable form scaffolding functionality.
For example:
class MyForm(Form): name = StringField('Name') class MyModelView(BaseModelView): form = MyForm
-
form_base_class
= <class 'flask_admin.form.BaseForm'>¶ Base form class. Will be used by form scaffolding function when creating model form.
Useful if you want to have custom contructor or override some fields.
Example:
class MyBaseForm(Form): def do_something(self): pass class MyModelView(BaseModelView): form_base_class = MyBaseForm
-
form_columns
= None¶ Collection of the model field names for the form. If set to None will get them from the model.
Example:
class MyModelView(BaseModelView): form_columns = ('name', 'email')
-
form_excluded_columns
¶ Collection of excluded form field names.
For example:
class MyModelView(BaseModelView): form_excluded_columns = ('last_name', 'email')
-
form_args
= None¶ Dictionary of form field arguments. Refer to WTForms documentation for list of possible options.
Example:
from wtforms.validators import required class MyModelView(BaseModelView): form_args = dict( name=dict(label='First Name', validators=[required()]) )
-
form_overrides
= None¶ Dictionary of form column overrides.
Example:
class MyModelView(BaseModelView): form_overrides = dict(name=wtf.FileField)
-
form_widget_args
= None¶ Dictionary of form widget rendering arguments. Use this to customize how widget is rendered without using custom template.
Example:
class MyModelView(BaseModelView): form_widget_args = { 'description': { 'rows': 10, 'style': 'color: black' } }
Changing the format of a DateTimeField will require changes to both form_widget_args and form_args.
Example:
form_args = dict( start=dict(format='%Y-%m-%d %I:%M %p') # changes how the input is parsed by strptime (12 hour time) ) form_widget_args = dict( start={'data-date-format': u'yyyy-mm-dd HH:ii P', 'data-show-meridian': 'True'} # changes how the DateTimeField displays the time )
-
form_extra_fields
= None¶ Dictionary of additional fields.
Example:
class MyModelView(BaseModelView): form_extra_fields = { password: PasswordField('Password') }
You can control order of form fields using
form_columns
property. For example:class MyModelView(BaseModelView): form_columns = ('name', 'email', 'password', 'secret') form_extra_fields = { password: PasswordField('Password') }
In this case, password field will be put between email and secret fields that are autogenerated.
-
form_ajax_refs
= None¶ Use AJAX for foreign key model loading.
Should contain dictionary, where key is field name and value is either a dictionary which configures AJAX lookups or backend-specific AjaxModelLoader class instance.
For example, it can look like:
class MyModelView(BaseModelView): form_ajax_refs = { 'user': { 'fields': ('first_name', 'last_name', 'email') 'page_size': 10 } }
Or with SQLAlchemy backend like this:
class MyModelView(BaseModelView): form_ajax_refs = { 'user': QueryAjaxModelLoader('user', db.session, User, fields=['email'], page_size=10) }
If you need custom loading functionality, you can implement your custom loading behavior in your AjaxModelLoader class.
-
form_create_rules
= None¶ Customized rules for the create form. Override form_rules if present.
-
form_edit_rules
= None¶ Customized rules for the edit form. Override form_rules if present.
-
action_disallowed_list
¶ Set of disallowed action names. For example, if you want to disable mass model deletion, do something like this:
- class MyModelView(BaseModelView):
- action_disallowed_list = [‘delete’]
-
page_size
= 20¶ Default page size for pagination.
-
after_model_change
(form, model, is_created)[source]¶ Perform some actions after a model was created or updated and committed to the database.
Called from create_model after successful database commit.
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that was created/updated
- is_created – True if model was created, False if model was updated
-
after_model_delete
(model)[source]¶ Perform some actions after a model was deleted and committed to the database.
Called from delete_model after successful database commit (if it has any meaning for a store backend).
By default does nothing.
Parameters: model – Model that was deleted
-
column_editable_list
= None¶ Collection of the columns which can be edited from the list view.
For example:
class MyModelView(BaseModelView): column_editable_list = ('name', 'last_name')
-
create_form
(obj=None)[source]¶ Instantiate model creation form and return it.
Override to implement custom behavior.
-
create_model
(form)[source]¶ Create model from the form.
Returns the model instance if operation succeeded.
Must be implemented in the child class.
Parameters: form – Form instance
-
delete_form
()[source]¶ Instantiate model delete form and return it.
Override to implement custom behavior.
The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility.
-
delete_model
(model)[source]¶ Delete model.
Returns True if operation succeeded.
Must be implemented in the child class.
Parameters: model – Model instance
-
edit_form
(obj=None)[source]¶ Instantiate model editing form and return it.
Override to implement custom behavior.
-
form_rules
= None¶ List of rendering rules for model creation form.
This property changed default form rendering behavior and makes possible to rearrange order of rendered fields, add some text between fields, group them, etc. If not set, will use default Flask-Admin form rendering logic.
Here’s simple example which illustrates how to use:
from flask_admin.form import rules class MyModelView(ModelView): form_rules = [ # Define field set with header text and four fields rules.FieldSet(('first_name', 'last_name', 'email', 'phone'), 'User'), # ... and it is just shortcut for: rules.Header('User'), rules.Field('first_name'), rules.Field('last_name'), # ... # It is possible to create custom rule blocks: MyBlock('Hello World'), # It is possible to call macros from current context rules.Macro('my_macro', foobar='baz') ]
-
get_column_name
(field)[source]¶ Return a human-readable column name.
Parameters: field – Model field name.
-
get_create_form
()[source]¶ Create form class for model creation view.
Override to implement customized behavior.
-
get_delete_form
()[source]¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()[source]¶ Create form class for model editing view.
Override to implement customized behavior.
-
get_filter_arg
(index, flt)[source]¶ Given a filter flt, return a unique name for that filter in this view.
Does not include the flt[n]_ portion of the filter name.
Parameters: - index – Filter index in _filters array
- flt – Filter instance
-
get_filters
()[source]¶ Return a list of filter objects.
If your model backend implementation does not support filters, override this method and return None.
-
get_form
()[source]¶ Get form class.
If
self.form
is set, will return it and will callself.scaffold_form
otherwise.Override to implement customized behavior.
-
get_list
(page, sort_field, sort_desc, search, filters)[source]¶ Return a paginated and sorted list of models from the data source.
Must be implemented in the child class.
Parameters: - page – Page number, 0 based. Can be set to None if it is first page.
- sort_field – Sort column name or None.
- sort_desc – If set to True, sorting is in descending order.
- search – Search query
- filters – List of filter tuples. First value in a tuple is a search index, second value is a search value.
-
get_list_columns
()[source]¶ Returns a list of the model field names. If column_list was set, returns it. Otherwise calls scaffold_list_columns to generate the list from the model.
-
get_list_form
()[source]¶ Get form class for the editable list view.
Uses only validators from form_args to build the form class.
Allows overriding the editable list view field/widget. For example:
from flask_admin.model.fields import ListEditableFieldList from flask_admin.model.widgets import XEditableWidget class CustomWidget(XEditableWidget): def get_kwargs(self, subfield, kwargs): if subfield.type == 'TextAreaField': kwargs['data-type'] = 'textarea' kwargs['data-rows'] = '20' # elif: kwargs for other fields return kwargs class CustomFieldList(ListEditableFieldList): widget = CustomWidget() class MyModelView(BaseModelView): def get_list_form(self): return self.scaffold_list_form(CustomFieldList)
-
get_list_value
(context, model, name)[source]¶ Returns the value to be displayed in the list view
Parameters: - context –
jinja2.runtime.Context
- model – Model instance
- name – Field name
- context –
-
get_one
(id)[source]¶ Return one model by its id.
Must be implemented in the child class.
Parameters: id – Model id
-
get_sortable_columns
()[source]¶ Returns a dictionary of the sortable columns. Key is a model field name and value is sort column (for example - attribute).
If column_sortable_list is set, will use it. Otherwise, will call scaffold_sortable_columns to get them from the model.
-
handle_filter
(filter)[source]¶ Postprocess (add joins, etc) for a filter.
Parameters: filter – Filter object to postprocess
-
init_search
()[source]¶ Initialize search. If data provider does not support search, init_search will return False.
-
is_action_allowed
(name)[source]¶ Override this method to allow or disallow actions based on some condition.
The default implementation only checks if the particular action is not in action_disallowed_list.
-
is_sortable
(name)[source]¶ Verify if column is sortable.
Not case-sensitive.
Parameters: name – Column name.
-
is_valid_filter
(filter)[source]¶ Verify that the provided filter object is valid.
Override in model backend implementation to verify if the provided filter type is allowed.
Parameters: filter – Filter object to verify.
-
list_form
(obj=None)[source]¶ Instantiate model editing form for list view and return it.
Override to implement custom behavior.
-
named_filter_urls
= False¶ Set to True to use human-readable names for filters in URL parameters.
False by default so as to be robust across translations.
Changing this parameter will break any existing URLs that have filters.
-
on_form_prefill
(form, id)[source]¶ Perform additional actions to pre-fill the edit form.
Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.
By default does nothing.
You only need to override this if you have added custom fields that depend on the database contents in a way that Flask-admin can’t figure out by itself. Fields that were added by name of a normal column or relationship should work out of the box.
Parameters: - form – Form instance
- id – id of the object that is going to be edited
-
on_model_change
(form, model, is_created)[source]¶ Perform some actions after a model is created or updated.
Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that will be created/updated
- is_created – Will be set to True if model was created and to False if edited
-
on_model_delete
(model)[source]¶ Perform some actions before a model is deleted.
Called from delete_model in the same transaction (if it has any meaning for a store backend).
By default do nothing.
-
scaffold_filters
(name)[source]¶ Generate filter object for the given name
Parameters: name – Name of the field
-
scaffold_form
()[source]¶ Create form.BaseForm inherited class from the model. Must be implemented in the child class.
-
scaffold_list_columns
()[source]¶ Return list of the model field names. Must be implemented in the child class.
Expected return format is list of tuples with field name and display text. For example:
['name', 'first_name', 'last_name']
-
scaffold_list_form
(custom_fieldlist=<class 'flask_admin.model.fields.ListEditableFieldList'>, validators=None)[source]¶ Create form for the index_view using only the columns from self.column_editable_list.
Parameters: - validators – form_args dict with only validators {‘name’: {‘validators’: [required()]}}
- custom_fieldlist – A WTForm FieldList class. By default, ListEditableFieldList.
Must be implemented in the child class.
-
scaffold_sortable_columns
()[source]¶ Returns dictionary of sortable columns. Must be implemented in the child class.
Expected return format is a dictionary, where keys are field names and values are property names.
-
simple_list_pager
= False¶ Enable or disable simple list pager. If enabled, model interface would not run count query and will only show prev/next pager buttons.
flask_admin.form.rules
¶
-
class
NestedRule
(rules=[], separator='')[source]¶ Nested rule. Can contain child rules and render them.
flask_admin.form.fields
¶
-
class
TimeField
(label=None, validators=None, formats=None, default_format=None, widget_format=None, **kwargs)[source]¶ A text field which stores a datetime.time object. Accepts time string in multiple formats: 20:10, 20:10:00, 10:00 am, 9:30pm, etc.
flask_admin.form.upload
¶
-
class
FileUploadField
(label=None, validators=None, base_path=None, relative_path=None, namegen=None, allowed_extensions=None, permission=438, allow_overwrite=True, **kwargs)[source]¶ Customizable file-upload field.
Saves file to configured path, handles updates and deletions. Inherits from StringField, resulting filename will be stored as string.
-
__init__
(label=None, validators=None, base_path=None, relative_path=None, namegen=None, allowed_extensions=None, permission=438, allow_overwrite=True, **kwargs)[source]¶ Constructor.
Parameters: - label – Display label
- validators – Validators
- base_path – Absolute path to the directory which will store files
- relative_path – Relative path from the directory. Will be prepended to the file name for uploaded files. Flask-Admin uses urlparse.urljoin to generate resulting filename, so make sure you have trailing slash.
- namegen –
Function that will generate filename from the model and uploaded file object. Please note, that model is “dirty” model object, before it was committed to database.
For example:
import os.path as op def prefix_name(obj, file_data): parts = op.splitext(file_data.filename) return secure_filename('file-%s%s' % parts) class MyForm(BaseForm): upload = FileUploadField('File', namegen=prefix_name)
- allowed_extensions – List of allowed extensions. If not provided, will allow any file.
- allow_overwrite – Whether to overwrite existing files in upload directory. Defaults to True.
New in version 1.1.1: The allow_overwrite parameter was added.
-
-
class
ImageUploadField
(label=None, validators=None, base_path=None, relative_path=None, namegen=None, allowed_extensions=None, max_size=None, thumbgen=None, thumbnail_size=None, permission=438, url_relative_path=None, endpoint='static', **kwargs)[source]¶ Image upload field.
Does image validation, thumbnail generation, updating and deleting images.
Requires PIL (or Pillow) to be installed.
-
__init__
(label=None, validators=None, base_path=None, relative_path=None, namegen=None, allowed_extensions=None, max_size=None, thumbgen=None, thumbnail_size=None, permission=438, url_relative_path=None, endpoint='static', **kwargs)[source]¶ Constructor.
Parameters: - label – Display label
- validators – Validators
- base_path – Absolute path to the directory which will store files
- relative_path – Relative path from the directory. Will be prepended to the file name for uploaded files. Flask-Admin uses urlparse.urljoin to generate resulting filename, so make sure you have trailing slash.
- namegen –
Function that will generate filename from the model and uploaded file object. Please note, that model is “dirty” model object, before it was committed to database.
For example:
import os.path as op def prefix_name(obj, file_data): parts = op.splitext(file_data.filename) return secure_filename('file-%s%s' % parts) class MyForm(BaseForm): upload = FileUploadField('File', namegen=prefix_name)
- allowed_extensions – List of allowed extensions. If not provided, then gif, jpg, jpeg, png and tiff will be allowed.
- max_size –
Tuple of (width, height, force) or None. If provided, Flask-Admin will resize image to the desired size.
Width and height is in pixels. If force is set to True, will try to fit image into dimensions and keep aspect ratio, otherwise will just resize to target size.
- thumbgen –
Thumbnail filename generation function. All thumbnails will be saved as JPEG files, so there’s no need to keep original file extension.
For example:
import os.path as op def thumb_name(filename): name, _ = op.splitext(filename) return secure_filename('%s-thumb.jpg' % name) class MyForm(BaseForm): upload = ImageUploadField('File', thumbgen=prefix_name)
- thumbnail_size –
Tuple or (width, height, force) values. If not provided, thumbnail won’t be created.
Width and height is in pixels. If force is set to True, will try to fit image into dimensions and keep aspect ratio, otherwise will just resize to target size.
- url_relative_path –
Relative path from the root of the static directory URL. Only gets used when generating preview image URLs.
For example, your model might store just file names (relative_path set to None), but base_path is pointing to subdirectory.
- endpoint – Static endpoint for images. Used by widget to display previews. Defaults to ‘static’.
-
flask_admin.tools
¶
-
import_module
(name, required=True)[source]¶ Import module by name
Parameters: - name – Module name
- required – If set to True and module was not found - will throw exception. If set to False and module was not found - will return None. Default is True.
-
import_attribute
(name)[source]¶ Import attribute using string reference.
Parameters: name – String reference. Raises ImportError or AttributeError if module or attribute do not exist.
Example:
import_attribute('a.b.c.foo')
-
module_not_found
(additional_depth=0)[source]¶ Checks if ImportError was raised because module does not exist or something inside it raised ImportError
Parameters: additional_depth – supply int of depth of your call if you’re not doing import on the same level of code - f.e., if you call function, which is doing import, you should pass 1 for single additional level of depth
flask_admin.actions
¶
-
action
(name, text, confirmation=None)[source]¶ Use this decorator to expose actions that span more than one entity (model, file, etc)
Parameters: - name – Action name
- text – Action text.
- confirmation – Confirmation text. If not provided, action will be executed unconditionally.
-
class
ActionsMixin
[source]¶ Actions mixin.
In some cases, you might work with more than one “entity” (model, file, etc) in your admin view and will want to perform actions on a group of entities simultaneously.
In this case, you can add this functionality by doing this: 1. Add this mixin to your administrative view class 2. Call init_actions in your class constructor 3. Expose actions view 4. Import actions.html library and add call library macros in your template
flask_admin.contrib.sqla
¶
SQLAlchemy model backend implementation.
-
class
ModelView
(model, session, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ SQLAlchemy model view
Usage sample:
admin = Admin() admin.add_view(ModelView(User, db.session))
Class inherits configuration options from
BaseModelView
and they’re not displayed here.Enable automatic detection of displayed foreign keys in this view and perform automatic joined loading for related models to improve query performance.
Please note that detection is not recursive: if __unicode__ method of related model uses another model to generate string representation, it will still make separate database call.
List of parameters for SQLAlchemy subqueryload. Overrides column_auto_select_related property.
For example:
class PostAdmin(ModelView): column_select_related_list = ('user', 'city')
You can also use properties:
class PostAdmin(ModelView): column_select_related_list = (Post.user, Post.city)
Please refer to the subqueryload on list of possible values.
-
column_searchable_list
¶ Collection of the searchable columns.
Example:
class MyModelView(ModelView): column_searchable_list = ('name', 'email')
You can also pass columns:
class MyModelView(ModelView): column_searchable_list = (User.name, User.email)
The following search rules apply:
- If you enter ZZZ in the UI search field, it will generate ILIKE ‘%ZZZ%’ statement against searchable columns.
- If you enter multiple words, each word will be searched separately, but only rows that contain all words will be displayed. For example, searching for ‘abc def’ will find all rows that contain ‘abc’ and ‘def’ in one or more columns.
- If you prefix your search term with ^, it will find all rows that start with ^. So, if you entered ^ZZZ, ILIKE ‘ZZZ%’ will be used.
- If you prefix your search term with =, it will perform an exact match. For example, if you entered =ZZZ, the statement ILIKE ‘ZZZ’ will be used.
-
column_filters
= None¶ Collection of the column filters.
Can contain either field names or instances of
flask_admin.contrib.sqla.filters.BaseFilter
classes.For example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
or:
class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(User.name, 'Name'))
-
filter_converter
= <flask_admin.contrib.sqla.filters.FilterConverter object>¶ Field to filter converter.
Override this attribute to use non-default converter.
-
model_form_converter
= <class 'flask_admin.contrib.sqla.form.AdminModelConverter'>¶ Model form conversion class. Use this to implement custom field conversion logic.
For example:
class MyModelConverter(AdminModelConverter): pass class MyAdminView(ModelView): model_form_converter = MyModelConverter
-
inline_model_form_converter
= <class 'flask_admin.contrib.sqla.form.InlineModelConverter'>¶ Inline model conversion class. If you need some kind of post-processing for inline forms, you can customize behavior by doing something like this:
class MyInlineModelConverter(AdminModelConverter): def post_process(self, form_class, info): form_class.value = wtf.StringField('value') return form_class class MyAdminView(ModelView): inline_model_form_converter = MyInlineModelConverter
-
fast_mass_delete
= False¶ If set to False and user deletes more than one model using built in action, all models will be read from the database and then deleted one by one giving SQLAlchemy a chance to manually cleanup any dependencies (many-to-many relationships, etc).
If set to True, will run a DELETE statement which is somewhat faster, but may leave corrupted data if you forget to configure DELETE CASCADE for your model.
-
inline_models
= None¶ Inline related-model editing for models with parent-child relations.
Accepts enumerable with one of the following possible values:
Child model class:
class MyModelView(ModelView): inline_models = (Post,)
Child model class and additional options:
class MyModelView(ModelView): inline_models = [(Post, dict(form_columns=['title']))]
Django-like
InlineFormAdmin
class instance:class MyInlineModelForm(InlineFormAdmin): form_columns = ('title', 'date') class MyModelView(ModelView): inline_models = (MyInlineModelForm(MyInlineModel),)
You can customize the generated field name by:
Using the form_name property as a key to the options dictionary:
- class MyModelView(ModelView):
inline_models = ((Post, dict(form_label=’Hello’)))
Using forward relation name and column_labels property:
- class Model1(Base):
pass
- class Model2(Base):
# ... model1 = relation(Model1, backref=’models’)
- class MyModel1View(Base):
inline_models = (Model2,) column_labels = {‘models’: ‘Hello’}
-
form_choices
= None¶ Map choices to form fields
Example:
class MyModelView(BaseModelView): form_choices = {'my_form_field': [ ('db_value', 'display_value'), ]
-
form_optional_types
= (<class 'sqlalchemy.sql.sqltypes.Boolean'>,)¶ List of field types that should be optional if column is not nullable.
Example:
class MyModelView(BaseModelView): form_optional_types = (Boolean, Unicode)
-
action_view
(*args, **kwargs)¶ Mass-model action view.
-
after_model_change
(form, model, is_created)¶ Perform some actions after a model was created or updated and committed to the database.
Called from create_model after successful database commit.
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that was created/updated
- is_created – True if model was created, False if model was updated
-
after_model_delete
(model)¶ Perform some actions after a model was deleted and committed to the database.
Called from delete_model after successful database commit (if it has any meaning for a store backend).
By default does nothing.
Parameters: model – Model that was deleted
-
ajax_update
(*args, **kwargs)¶ Edits a single column of a record in list view.
-
column_display_all_relations
¶ Controls if list view should display all relations, not only many-to-one.
-
create_blueprint
(admin)¶ Create Flask blueprint.
-
create_form
(obj=None)¶ Instantiate model creation form and return it.
Override to implement custom behavior.
-
create_view
(*args, **kwargs)¶ Create model view
-
delete_form
()¶ Instantiate model delete form and return it.
Override to implement custom behavior.
The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility.
-
delete_view
(*args, **kwargs)¶ Delete model view. Only POST method is allowed.
-
edit_form
(obj=None)¶ Instantiate model editing form and return it.
Override to implement custom behavior.
-
edit_view
(*args, **kwargs)¶ Edit model view
-
get_actions_list
()¶ Return a list and a dictionary of allowed actions.
-
get_column_name
(field)¶ Return a human-readable column name.
Parameters: field – Model field name.
-
get_count_query
()[source]¶ Return a the count query for the model type
A query(self.model).count() approach produces an excessive subquery, so query(func.count(‘*’)) should be used instead.
See #45a2723 commit message for details.
-
get_create_form
()¶ Create form class for model creation view.
Override to implement customized behavior.
-
get_delete_form
()¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()¶ Create form class for model editing view.
Override to implement customized behavior.
-
get_filter_arg
(index, flt)¶ Given a filter flt, return a unique name for that filter in this view.
Does not include the flt[n]_ portion of the filter name.
Parameters: - index – Filter index in _filters array
- flt – Filter instance
-
get_filters
()¶ Return a list of filter objects.
If your model backend implementation does not support filters, override this method and return None.
-
get_form
()¶ Get form class.
If
self.form
is set, will return it and will callself.scaffold_form
otherwise.Override to implement customized behavior.
-
get_list
(page, sort_column, sort_desc, search, filters, execute=True)[source]¶ Return models from the database.
Parameters: - page – Page number
- sort_column – Sort column name
- sort_desc – Descending or ascending sort
- search – Search query
- execute – Execute query immediately? Default is True
- filters – List of filter tuples
-
get_list_columns
()¶ Returns a list of the model field names. If column_list was set, returns it. Otherwise calls scaffold_list_columns to generate the list from the model.
-
get_list_form
()¶ Get form class for the editable list view.
Uses only validators from form_args to build the form class.
Allows overriding the editable list view field/widget. For example:
from flask_admin.model.fields import ListEditableFieldList from flask_admin.model.widgets import XEditableWidget class CustomWidget(XEditableWidget): def get_kwargs(self, subfield, kwargs): if subfield.type == 'TextAreaField': kwargs['data-type'] = 'textarea' kwargs['data-rows'] = '20' # elif: kwargs for other fields return kwargs class CustomFieldList(ListEditableFieldList): widget = CustomWidget() class MyModelView(BaseModelView): def get_list_form(self): return self.scaffold_list_form(CustomFieldList)
-
get_list_value
(context, model, name)¶ Returns the value to be displayed in the list view
Parameters: - context –
jinja2.runtime.Context
- model – Model instance
- name – Field name
- context –
-
get_pk_value
(model)[source]¶ Return the primary key value from a model object. If there are multiple primary keys, they’re encoded into string representation.
-
get_query
()[source]¶ Return a query for the model type.
If you override this method, don’t forget to override get_count_query as well.
This method can be used to set a “persistent filter” on an index_view.
Example:
class MyView(ModelView): def get_query(self): return super(MyView, self).get_query().filter(User.username == current_user.username)
-
get_sortable_columns
()[source]¶ Returns a dictionary of the sortable columns. Key is a model field name and value is sort column (for example - attribute).
If column_sortable_list is set, will use it. Otherwise, will call scaffold_sortable_columns to get them from the model.
-
get_url
(endpoint, **kwargs)¶ Generate URL for the endpoint. If you want to customize URL generation logic (persist some query string argument, for example), this is right place to do it.
Parameters: - endpoint – Flask endpoint name
- kwargs – Arguments for url_for
-
handle_action
(return_view=None)¶ Handle action request.
Parameters: return_view – Name of the view to return to after the request. If not provided, will return user to the index view.
-
inaccessible_callback
(name, **kwargs)¶ Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to customize the behaviour.
-
index_view
(*args, **kwargs)¶ List view
-
init_actions
()¶ Initialize list of actions for the current administrative view.
-
init_search
()[source]¶ Initialize search. Returns True if search is supported for this view.
For SQLAlchemy, this will initialize internal fields: list of column objects used for filtering, etc.
-
is_accessible
()¶ Override this method to add permission checks.
Flask-Admin does not make any assumptions about the authentication system used in your application, so it is up to you to implement it.
By default, it will allow access for everyone.
-
is_editable
(name)¶ Verify if column is editable.
Parameters: name – Column name.
-
is_sortable
(name)¶ Verify if column is sortable.
Not case-sensitive.
Parameters: name – Column name.
-
is_valid_filter
(filter)¶ Verify that the provided filter object is valid.
Override in model backend implementation to verify if the provided filter type is allowed.
Parameters: filter – Filter object to verify.
-
is_visible
()¶ Override this method if you want dynamically hide or show administrative views from Flask-Admin menu structure
By default, item is visible in menu.
Please note that item should be both visible and accessible to be displayed in menu.
-
list_form
(obj=None)¶ Instantiate model editing form for list view and return it.
Override to implement custom behavior.
-
on_form_prefill
(form, id)¶ Perform additional actions to pre-fill the edit form.
Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.
By default does nothing.
You only need to override this if you have added custom fields that depend on the database contents in a way that Flask-admin can’t figure out by itself. Fields that were added by name of a normal column or relationship should work out of the box.
Parameters: - form – Form instance
- id – id of the object that is going to be edited
-
on_model_change
(form, model, is_created)¶ Perform some actions after a model is created or updated.
Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that will be created/updated
- is_created – Will be set to True if model was created and to False if edited
-
on_model_delete
(model)¶ Perform some actions before a model is deleted.
Called from delete_model in the same transaction (if it has any meaning for a store backend).
By default do nothing.
-
render
(template, **kwargs)¶ Render template
Parameters: - template – Template path to render
- kwargs – Template arguments
-
scaffold_auto_joins
()[source]¶ Return a list of joined tables by going through the displayed columns.
-
scaffold_inline_form_models
(form_class)[source]¶ Contribute inline models to the form
Parameters: form_class – Form class
-
scaffold_list_form
(custom_fieldlist=<class 'flask_admin.model.fields.ListEditableFieldList'>, validators=None)[source]¶ Create form for the index_view using only the columns from self.column_editable_list.
Parameters: - validators – form_args dict with only validators {‘name’: {‘validators’: [required()]}}
- custom_fieldlist – A WTForm FieldList class. By default, ListEditableFieldList.
-
scaffold_pk
()[source]¶ Return the primary key name(s) from a model If model has single primary key, will return a string and tuple otherwise
-
scaffold_sortable_columns
()[source]¶ Return a dictionary of sortable columns. Key is column name, value is sort column/field.
-
update_model
(form, model)[source]¶ Update model from form.
Parameters: - form – Form instance
- model – Model instance
-
validate_form
(form)¶ Validate the form on submit.
Parameters: form – Form to validate
flask_admin.contrib.mongoengine
¶
MongoEngine model backend implementation.
-
class
ModelView
(model, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ MongoEngine model scaffolding.
Class inherits configuration options fromBaseModelView
and they’re not displayed here.-
column_filters
= None¶ Collection of the column filters.
Can contain either field names or instances of
flask_admin.contrib.mongoengine.filters.BaseFilter
classes.For example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
or:
class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(User.name, 'Name'))
-
column_type_formatters
= {<class 'mongoengine.base.datastructures.BaseList'>: <function list_formatter at 0x7f89d3b99848>, <type 'list'>: <function list_formatter at 0x7f89d3b99848>, <type 'bool'>: <function bool_formatter at 0x7f89d3b997d0>, <class 'mongoengine.fields.GridFSProxy'>: <function grid_formatter at 0x7f89d3b59e60>, <class 'mongoengine.fields.ImageGridFsProxy'>: <function grid_image_formatter at 0x7f89d3b5e230>, <type 'NoneType'>: <function empty_formatter at 0x7f89d3b996e0>}¶ Customized type formatters for MongoEngine backend
-
filter_converter
= <flask_admin.contrib.mongoengine.filters.FilterConverter object>¶ Field to filter converter.
Override this attribute to use a non-default converter.
-
model_form_converter
= <class 'flask_admin.contrib.mongoengine.form.CustomModelConverter'>¶ Model form conversion class. Use this to implement custom field conversion logic.
Custom class should be derived from the flask_admin.contrib.mongoengine.form.CustomModelConverter.
For example:
class MyModelConverter(AdminModelConverter): pass class MyAdminView(ModelView): model_form_converter = MyModelConverter
-
allowed_search_types
= (<class 'mongoengine.fields.StringField'>, <class 'mongoengine.fields.URLField'>, <class 'mongoengine.fields.EmailField'>)¶ List of allowed search field types.
-
form_subdocuments
= None¶ Subdocument configuration options.
This field accepts dictionary, where key is field name and value is either dictionary or instance of the flask_admin.contrib.EmbeddedForm.
Consider following example:
class Comment(db.EmbeddedDocument): name = db.StringField(max_length=20, required=True) value = db.StringField(max_length=20) class Post(db.Document): text = db.StringField(max_length=30) data = db.EmbeddedDocumentField(Comment) class MyAdmin(ModelView): form_subdocuments = { 'data': { 'form_columns': ('name',) } }
In this example, Post model has child Comment subdocument. When generating form for Comment embedded document, Flask-Admin will only create name field.
It is also possible to use class-based embedded document configuration:
class CommentEmbed(EmbeddedForm): form_columns = ('name',) class MyAdmin(ModelView): form_subdocuments = { 'data': CommentEmbed() }
Arbitrary depth nesting is supported:
class SomeEmbed(EmbeddedForm): form_excluded_columns = ('test',) class CommentEmbed(EmbeddedForm): form_columns = ('name',) form_subdocuments = { 'inner': SomeEmbed() } class MyAdmin(ModelView): form_subdocuments = { 'data': CommentEmbed() }
There’s also support for forms embedded into ListField. All you have to do is to create nested rule with None as a name. Even though it is slightly confusing, but that’s how Flask-MongoEngine creates form fields embedded into ListField:
class Comment(db.EmbeddedDocument): name = db.StringField(max_length=20, required=True) value = db.StringField(max_length=20) class Post(db.Document): text = db.StringField(max_length=30) data = db.ListField(db.EmbeddedDocumentField(Comment)) class MyAdmin(ModelView): form_subdocuments = { 'data': { 'form_subdocuments': { None: { 'form_columns': ('name',) } } } }
-
action_view
(*args, **kwargs)¶ Mass-model action view.
-
after_model_change
(form, model, is_created)¶ Perform some actions after a model was created or updated and committed to the database.
Called from create_model after successful database commit.
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that was created/updated
- is_created – True if model was created, False if model was updated
-
after_model_delete
(model)¶ Perform some actions after a model was deleted and committed to the database.
Called from delete_model after successful database commit (if it has any meaning for a store backend).
By default does nothing.
Parameters: model – Model that was deleted
-
ajax_update
(*args, **kwargs)¶ Edits a single column of a record in list view.
-
allowed_search_types
= (<class 'mongoengine.fields.StringField'>, <class 'mongoengine.fields.URLField'>, <class 'mongoengine.fields.EmailField'>) List of allowed search field types.
-
create_blueprint
(admin)¶ Create Flask blueprint.
-
create_form
(obj=None)¶ Instantiate model creation form and return it.
Override to implement custom behavior.
-
create_view
(*args, **kwargs)¶ Create model view
-
delete_form
()¶ Instantiate model delete form and return it.
Override to implement custom behavior.
The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility.
-
delete_view
(*args, **kwargs)¶ Delete model view. Only POST method is allowed.
-
edit_form
(obj=None)¶ Instantiate model editing form and return it.
Override to implement custom behavior.
-
edit_view
(*args, **kwargs)¶ Edit model view
-
get_actions_list
()¶ Return a list and a dictionary of allowed actions.
-
get_column_name
(field)¶ Return a human-readable column name.
Parameters: field – Model field name.
-
get_create_form
()¶ Create form class for model creation view.
Override to implement customized behavior.
-
get_delete_form
()¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()¶ Create form class for model editing view.
Override to implement customized behavior.
-
get_filter_arg
(index, flt)¶ Given a filter flt, return a unique name for that filter in this view.
Does not include the flt[n]_ portion of the filter name.
Parameters: - index – Filter index in _filters array
- flt – Filter instance
-
get_filters
()¶ Return a list of filter objects.
If your model backend implementation does not support filters, override this method and return None.
-
get_form
()¶ Get form class.
If
self.form
is set, will return it and will callself.scaffold_form
otherwise.Override to implement customized behavior.
-
get_list
(page, sort_column, sort_desc, search, filters, execute=True)[source]¶ Get list of objects from MongoEngine
Parameters: - page – Page number
- sort_column – Sort column
- sort_desc – Sort descending
- search – Search criteria
- filters – List of applied filters
- execute – Run query immediately or not
-
get_list_columns
()¶ Returns a list of the model field names. If column_list was set, returns it. Otherwise calls scaffold_list_columns to generate the list from the model.
-
get_list_form
()¶ Get form class for the editable list view.
Uses only validators from form_args to build the form class.
Allows overriding the editable list view field/widget. For example:
from flask_admin.model.fields import ListEditableFieldList from flask_admin.model.widgets import XEditableWidget class CustomWidget(XEditableWidget): def get_kwargs(self, subfield, kwargs): if subfield.type == 'TextAreaField': kwargs['data-type'] = 'textarea' kwargs['data-rows'] = '20' # elif: kwargs for other fields return kwargs class CustomFieldList(ListEditableFieldList): widget = CustomWidget() class MyModelView(BaseModelView): def get_list_form(self): return self.scaffold_list_form(CustomFieldList)
-
get_list_value
(context, model, name)¶ Returns the value to be displayed in the list view
Parameters: - context –
jinja2.runtime.Context
- model – Model instance
- name – Field name
- context –
-
get_pk_value
(model)[source]¶ Return the primary key value from the model instance
Parameters: model – Model instance
-
get_query
()[source]¶ Returns the QuerySet for this view. By default, it returns all the objects for the current model.
-
get_sortable_columns
()¶ Returns a dictionary of the sortable columns. Key is a model field name and value is sort column (for example - attribute).
If column_sortable_list is set, will use it. Otherwise, will call scaffold_sortable_columns to get them from the model.
-
get_url
(endpoint, **kwargs)¶ Generate URL for the endpoint. If you want to customize URL generation logic (persist some query string argument, for example), this is right place to do it.
Parameters: - endpoint – Flask endpoint name
- kwargs – Arguments for url_for
-
handle_action
(return_view=None)¶ Handle action request.
Parameters: return_view – Name of the view to return to after the request. If not provided, will return user to the index view.
-
handle_filter
(filter)¶ Postprocess (add joins, etc) for a filter.
Parameters: filter – Filter object to postprocess
-
inaccessible_callback
(name, **kwargs)¶ Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to customize the behaviour.
-
index_view
(*args, **kwargs)¶ List view
-
init_actions
()¶ Initialize list of actions for the current administrative view.
-
is_accessible
()¶ Override this method to add permission checks.
Flask-Admin does not make any assumptions about the authentication system used in your application, so it is up to you to implement it.
By default, it will allow access for everyone.
-
is_editable
(name)¶ Verify if column is editable.
Parameters: name – Column name.
-
is_sortable
(name)¶ Verify if column is sortable.
Not case-sensitive.
Parameters: name – Column name.
-
is_valid_filter
(filter)[source]¶ Validate if the provided filter is a valid MongoEngine filter
Parameters: filter – Filter object
-
is_visible
()¶ Override this method if you want dynamically hide or show administrative views from Flask-Admin menu structure
By default, item is visible in menu.
Please note that item should be both visible and accessible to be displayed in menu.
-
list_form
(obj=None)¶ Instantiate model editing form for list view and return it.
Override to implement custom behavior.
-
model_form_converter
Model form conversion class. Use this to implement custom field conversion logic.
Custom class should be derived from the flask_admin.contrib.mongoengine.form.CustomModelConverter.
For example:
class MyModelConverter(AdminModelConverter): pass class MyAdminView(ModelView): model_form_converter = MyModelConverter
alias of
CustomModelConverter
-
object_id_converter
¶ Mongodb
_id
value conversion function. Default is bson.ObjectId. Use this if you are using String, Binary and etc.For example:
class MyModelView(BaseModelView): object_id_converter = int
or:
class MyModelView(BaseModelView): object_id_converter = str
alias of
ObjectId
-
on_form_prefill
(form, id)¶ Perform additional actions to pre-fill the edit form.
Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.
By default does nothing.
You only need to override this if you have added custom fields that depend on the database contents in a way that Flask-admin can’t figure out by itself. Fields that were added by name of a normal column or relationship should work out of the box.
Parameters: - form – Form instance
- id – id of the object that is going to be edited
-
on_model_change
(form, model, is_created)¶ Perform some actions after a model is created or updated.
Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that will be created/updated
- is_created – Will be set to True if model was created and to False if edited
-
on_model_delete
(model)¶ Perform some actions before a model is deleted.
Called from delete_model in the same transaction (if it has any meaning for a store backend).
By default do nothing.
-
render
(template, **kwargs)¶ Render template
Parameters: - template – Template path to render
- kwargs – Template arguments
-
scaffold_filters
(name)[source]¶ Return filter object(s) for the field
Parameters: name – Either field name or field instance
-
scaffold_list_form
(custom_fieldlist=<class 'flask_admin.model.fields.ListEditableFieldList'>, validators=None)[source]¶ Create form for the index_view using only the columns from self.column_editable_list.
Parameters: - validators – form_args dict with only validators {‘name’: {‘validators’: [required()]}}
- custom_fieldlist – A WTForm FieldList class. By default, ListEditableFieldList.
-
update_model
(form, model)[source]¶ Update model helper
Parameters: - form – Form instance
- model – Model instance to update
-
validate_form
(form)¶ Validate the form on submit.
Parameters: form – Form to validate
-
flask_admin.contrib.mongoengine.fields
¶
flask_admin.contrib.peewee
¶
Peewee model backend implementation.
-
class
ModelView
(model, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ Class inherits configuration options from
BaseModelView
and they’re not displayed here.-
column_filters
= None¶ Collection of the column filters.
Can contain either field names or instances of
flask_admin.contrib.peewee.filters.BaseFilter
classes.For example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
or:
class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(User.name, 'Name'))
-
filter_converter
= <flask_admin.contrib.peewee.filters.FilterConverter object>¶ Field to filter converter.
Override this attribute to use non-default converter.
-
model_form_converter
= <class 'flask_admin.contrib.peewee.form.CustomModelConverter'>¶ Model form conversion class. Use this to implement custom field conversion logic.
For example:
class MyModelConverter(AdminModelConverter): pass class MyAdminView(ModelView): model_form_converter = MyModelConverter
-
inline_model_form_converter
= <class 'flask_admin.contrib.peewee.form.InlineModelConverter'>¶ Inline model conversion class. If you need some kind of post-processing for inline forms, you can customize behavior by doing something like this:
class MyInlineModelConverter(AdminModelConverter): def post_process(self, form_class, info): form_class.value = TextField('value') return form_class class MyAdminView(ModelView): inline_model_form_converter = MyInlineModelConverter
-
fast_mass_delete
= False¶ If set to False and user deletes more than one model using actions, all models will be read from the database and then deleted one by one giving Peewee chance to manually cleanup any dependencies (many-to-many relationships, etc).
If set to True, will run DELETE statement which is somewhat faster, but might leave corrupted data if you forget to configure DELETE CASCADE for your model.
-
inline_models
= None¶ Inline related-model editing for models with parent to child relation.
Accept enumerable with one of the values:
Child model class:
class MyModelView(ModelView): inline_models = (Post,)
Child model class and additional options:
class MyModelView(ModelView): inline_models = [(Post, dict(form_columns=['title']))]
Django-like
InlineFormAdmin
class instance:class MyInlineModelForm(InlineFormAdmin): form_columns = ('title', 'date') class MyModelView(ModelView): inline_models = (MyInlineModelForm(MyInlineModel),)
You can customize generated field name by:
Using form_name property as option:
- class MyModelView(ModelView):
inline_models = ((Post, dict(form_label=’Hello’)))
Using field’s related_name:
- class Model1(Base):
# ... pass
- class Model2(Base):
# ... model1 = ForeignKeyField(related_name=”model_twos”)
- class MyModel1View(Base):
inline_models = (Model2,) column_labels = {‘model_ones’: ‘Hello’}
-
action_view
(*args, **kwargs)¶ Mass-model action view.
-
after_model_change
(form, model, is_created)¶ Perform some actions after a model was created or updated and committed to the database.
Called from create_model after successful database commit.
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that was created/updated
- is_created – True if model was created, False if model was updated
-
after_model_delete
(model)¶ Perform some actions after a model was deleted and committed to the database.
Called from delete_model after successful database commit (if it has any meaning for a store backend).
By default does nothing.
Parameters: model – Model that was deleted
-
ajax_update
(*args, **kwargs)¶ Edits a single column of a record in list view.
-
create_blueprint
(admin)¶ Create Flask blueprint.
-
create_form
(obj=None)¶ Instantiate model creation form and return it.
Override to implement custom behavior.
-
create_view
(*args, **kwargs)¶ Create model view
-
delete_form
()¶ Instantiate model delete form and return it.
Override to implement custom behavior.
The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility.
-
delete_view
(*args, **kwargs)¶ Delete model view. Only POST method is allowed.
-
edit_form
(obj=None)¶ Instantiate model editing form and return it.
Override to implement custom behavior.
-
edit_view
(*args, **kwargs)¶ Edit model view
-
get_actions_list
()¶ Return a list and a dictionary of allowed actions.
-
get_column_name
(field)¶ Return a human-readable column name.
Parameters: field – Model field name.
-
get_create_form
()¶ Create form class for model creation view.
Override to implement customized behavior.
-
get_delete_form
()¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()¶ Create form class for model editing view.
Override to implement customized behavior.
-
get_filter_arg
(index, flt)¶ Given a filter flt, return a unique name for that filter in this view.
Does not include the flt[n]_ portion of the filter name.
Parameters: - index – Filter index in _filters array
- flt – Filter instance
-
get_filters
()¶ Return a list of filter objects.
If your model backend implementation does not support filters, override this method and return None.
-
get_form
()¶ Get form class.
If
self.form
is set, will return it and will callself.scaffold_form
otherwise.Override to implement customized behavior.
-
get_list_columns
()¶ Returns a list of the model field names. If column_list was set, returns it. Otherwise calls scaffold_list_columns to generate the list from the model.
-
get_list_form
()¶ Get form class for the editable list view.
Uses only validators from form_args to build the form class.
Allows overriding the editable list view field/widget. For example:
from flask_admin.model.fields import ListEditableFieldList from flask_admin.model.widgets import XEditableWidget class CustomWidget(XEditableWidget): def get_kwargs(self, subfield, kwargs): if subfield.type == 'TextAreaField': kwargs['data-type'] = 'textarea' kwargs['data-rows'] = '20' # elif: kwargs for other fields return kwargs class CustomFieldList(ListEditableFieldList): widget = CustomWidget() class MyModelView(BaseModelView): def get_list_form(self): return self.scaffold_list_form(CustomFieldList)
-
get_list_value
(context, model, name)¶ Returns the value to be displayed in the list view
Parameters: - context –
jinja2.runtime.Context
- model – Model instance
- name – Field name
- context –
-
get_sortable_columns
()¶ Returns a dictionary of the sortable columns. Key is a model field name and value is sort column (for example - attribute).
If column_sortable_list is set, will use it. Otherwise, will call scaffold_sortable_columns to get them from the model.
-
get_url
(endpoint, **kwargs)¶ Generate URL for the endpoint. If you want to customize URL generation logic (persist some query string argument, for example), this is right place to do it.
Parameters: - endpoint – Flask endpoint name
- kwargs – Arguments for url_for
-
handle_action
(return_view=None)¶ Handle action request.
Parameters: return_view – Name of the view to return to after the request. If not provided, will return user to the index view.
-
handle_filter
(filter)¶ Postprocess (add joins, etc) for a filter.
Parameters: filter – Filter object to postprocess
-
inaccessible_callback
(name, **kwargs)¶ Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to customize the behaviour.
-
index_view
(*args, **kwargs)¶ List view
-
init_actions
()¶ Initialize list of actions for the current administrative view.
-
is_accessible
()¶ Override this method to add permission checks.
Flask-Admin does not make any assumptions about the authentication system used in your application, so it is up to you to implement it.
By default, it will allow access for everyone.
-
is_editable
(name)¶ Verify if column is editable.
Parameters: name – Column name.
-
is_sortable
(name)¶ Verify if column is sortable.
Not case-sensitive.
Parameters: name – Column name.
-
is_visible
()¶ Override this method if you want dynamically hide or show administrative views from Flask-Admin menu structure
By default, item is visible in menu.
Please note that item should be both visible and accessible to be displayed in menu.
-
list_form
(obj=None)¶ Instantiate model editing form for list view and return it.
Override to implement custom behavior.
-
on_form_prefill
(form, id)¶ Perform additional actions to pre-fill the edit form.
Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.
By default does nothing.
You only need to override this if you have added custom fields that depend on the database contents in a way that Flask-admin can’t figure out by itself. Fields that were added by name of a normal column or relationship should work out of the box.
Parameters: - form – Form instance
- id – id of the object that is going to be edited
-
on_model_change
(form, model, is_created)¶ Perform some actions after a model is created or updated.
Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that will be created/updated
- is_created – Will be set to True if model was created and to False if edited
-
on_model_delete
(model)¶ Perform some actions before a model is deleted.
Called from delete_model in the same transaction (if it has any meaning for a store backend).
By default do nothing.
-
render
(template, **kwargs)¶ Render template
Parameters: - template – Template path to render
- kwargs – Template arguments
-
scaffold_list_form
(custom_fieldlist=<class 'flask_admin.model.fields.ListEditableFieldList'>, validators=None)[source]¶ Create form for the index_view using only the columns from self.column_editable_list.
Parameters: - validators – form_args dict with only validators {‘name’: {‘validators’: [required()]}}
- custom_fieldlist – A WTForm FieldList class. By default, ListEditableFieldList.
-
validate_form
(form)¶ Validate the form on submit.
Parameters: form – Form to validate
-
flask_admin.contrib.pymongo
¶
PyMongo model backend implementation.
-
class
ModelView
(coll, name=None, category=None, endpoint=None, url=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ MongoEngine model scaffolding.
Class inherits configuration options fromBaseModelView
and they’re not displayed here.-
column_filters
= None¶ Collection of the column filters.
Should contain instances of
flask_admin.contrib.pymongo.filters.BasePyMongoFilter
classes.For example:
class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(User.name, 'Name'),)
-
action_view
(*args, **kwargs)¶ Mass-model action view.
-
after_model_change
(form, model, is_created)¶ Perform some actions after a model was created or updated and committed to the database.
Called from create_model after successful database commit.
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that was created/updated
- is_created – True if model was created, False if model was updated
-
after_model_delete
(model)¶ Perform some actions after a model was deleted and committed to the database.
Called from delete_model after successful database commit (if it has any meaning for a store backend).
By default does nothing.
Parameters: model – Model that was deleted
-
ajax_update
(*args, **kwargs)¶ Edits a single column of a record in list view.
-
create_blueprint
(admin)¶ Create Flask blueprint.
-
create_form
(obj=None)¶ Instantiate model creation form and return it.
Override to implement custom behavior.
-
create_view
(*args, **kwargs)¶ Create model view
-
delete_form
()¶ Instantiate model delete form and return it.
Override to implement custom behavior.
The delete form originally used a GET request, so delete_form accepts both GET and POST request for backwards compatibility.
-
delete_view
(*args, **kwargs)¶ Delete model view. Only POST method is allowed.
-
edit_view
(*args, **kwargs)¶ Edit model view
-
get_actions_list
()¶ Return a list and a dictionary of allowed actions.
-
get_column_name
(field)¶ Return a human-readable column name.
Parameters: field – Model field name.
-
get_create_form
()¶ Create form class for model creation view.
Override to implement customized behavior.
-
get_delete_form
()¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()¶ Create form class for model editing view.
Override to implement customized behavior.
-
get_filter_arg
(index, flt)¶ Given a filter flt, return a unique name for that filter in this view.
Does not include the flt[n]_ portion of the filter name.
Parameters: - index – Filter index in _filters array
- flt – Filter instance
-
get_filters
()¶ Return a list of filter objects.
If your model backend implementation does not support filters, override this method and return None.
-
get_form
()¶ Get form class.
If
self.form
is set, will return it and will callself.scaffold_form
otherwise.Override to implement customized behavior.
-
get_list
(page, sort_column, sort_desc, search, filters, execute=True)[source]¶ Get list of objects from MongoEngine
Parameters: - page – Page number
- sort_column – Sort column
- sort_desc – Sort descending
- search – Search criteria
- filters – List of applied fiters
- execute – Run query immediately or not
-
get_list_columns
()¶ Returns a list of the model field names. If column_list was set, returns it. Otherwise calls scaffold_list_columns to generate the list from the model.
-
get_list_form
()¶ Get form class for the editable list view.
Uses only validators from form_args to build the form class.
Allows overriding the editable list view field/widget. For example:
from flask_admin.model.fields import ListEditableFieldList from flask_admin.model.widgets import XEditableWidget class CustomWidget(XEditableWidget): def get_kwargs(self, subfield, kwargs): if subfield.type == 'TextAreaField': kwargs['data-type'] = 'textarea' kwargs['data-rows'] = '20' # elif: kwargs for other fields return kwargs class CustomFieldList(ListEditableFieldList): widget = CustomWidget() class MyModelView(BaseModelView): def get_list_form(self): return self.scaffold_list_form(CustomFieldList)
-
get_list_value
(context, model, name)¶ Returns the value to be displayed in the list view
Parameters: - context –
jinja2.runtime.Context
- model – Model instance
- name – Field name
- context –
-
get_pk_value
(model)[source]¶ Return primary key value from the model instance
Parameters: model – Model instance
-
get_sortable_columns
()¶ Returns a dictionary of the sortable columns. Key is a model field name and value is sort column (for example - attribute).
If column_sortable_list is set, will use it. Otherwise, will call scaffold_sortable_columns to get them from the model.
-
get_url
(endpoint, **kwargs)¶ Generate URL for the endpoint. If you want to customize URL generation logic (persist some query string argument, for example), this is right place to do it.
Parameters: - endpoint – Flask endpoint name
- kwargs – Arguments for url_for
-
handle_action
(return_view=None)¶ Handle action request.
Parameters: return_view – Name of the view to return to after the request. If not provided, will return user to the index view.
-
handle_filter
(filter)¶ Postprocess (add joins, etc) for a filter.
Parameters: filter – Filter object to postprocess
-
inaccessible_callback
(name, **kwargs)¶ Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to customize the behaviour.
-
index_view
(*args, **kwargs)¶ List view
-
init_actions
()¶ Initialize list of actions for the current administrative view.
-
is_accessible
()¶ Override this method to add permission checks.
Flask-Admin does not make any assumptions about the authentication system used in your application, so it is up to you to implement it.
By default, it will allow access for everyone.
-
is_editable
(name)¶ Verify if column is editable.
Parameters: name – Column name.
-
is_sortable
(name)¶ Verify if column is sortable.
Not case-sensitive.
Parameters: name – Column name.
-
is_valid_filter
(filter)[source]¶ Validate if it is valid MongoEngine filter
Parameters: filter – Filter object
-
is_visible
()¶ Override this method if you want dynamically hide or show administrative views from Flask-Admin menu structure
By default, item is visible in menu.
Please note that item should be both visible and accessible to be displayed in menu.
-
list_form
(obj=None)¶ Instantiate model editing form for list view and return it.
Override to implement custom behavior.
-
on_form_prefill
(form, id)¶ Perform additional actions to pre-fill the edit form.
Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.
By default does nothing.
You only need to override this if you have added custom fields that depend on the database contents in a way that Flask-admin can’t figure out by itself. Fields that were added by name of a normal column or relationship should work out of the box.
Parameters: - form – Form instance
- id – id of the object that is going to be edited
-
on_model_change
(form, model, is_created)¶ Perform some actions after a model is created or updated.
Called from create_model and update_model in the same transaction (if it has any meaning for a store backend).
By default does nothing.
Parameters: - form – Form used to create/update model
- model – Model that will be created/updated
- is_created – Will be set to True if model was created and to False if edited
-
on_model_delete
(model)¶ Perform some actions before a model is deleted.
Called from delete_model in the same transaction (if it has any meaning for a store backend).
By default do nothing.
-
render
(template, **kwargs)¶ Render template
Parameters: - template – Template path to render
- kwargs – Template arguments
-
scaffold_filters
(attr)[source]¶ Return filter object(s) for the field
Parameters: name – Either field name or field instance
-
scaffold_list_form
(custom_fieldlist=<class 'flask_admin.model.fields.ListEditableFieldList'>, validators=None)¶ Create form for the index_view using only the columns from self.column_editable_list.
Parameters: - validators – form_args dict with only validators {‘name’: {‘validators’: [required()]}}
- custom_fieldlist – A WTForm FieldList class. By default, ListEditableFieldList.
Must be implemented in the child class.
-
update_model
(form, model)[source]¶ Update model helper
Parameters: - form – Form instance
- model – Model instance to update
-
validate_form
(form)¶ Validate the form on submit.
Parameters: form – Form to validate
-
flask_admin.contrib.fileadmin
¶
-
class
FileAdmin
(base_path, base_url=None, name=None, category=None, endpoint=None, url=None, verify_path=True, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶ Simple file-management interface.
Parameters: - path – Path to the directory which will be managed
- base_url – Optional base URL for the directory. Will be used to generate static links to the files. If not defined, a route will be created to serve uploaded files.
Sample usage:
import os.path as op from flask_admin import Admin from flask_admin.contrib.fileadmin import FileAdmin admin = Admin() path = op.join(op.dirname(__file__), 'static') admin.add_view(FileAdmin(path, '/static/', name='Static Files'))
-
can_upload
= True¶ Is file upload allowed.
-
can_delete
= True¶ Is file deletion allowed.
-
can_delete_dirs
= True¶ Is recursive directory deletion is allowed.
-
can_mkdir
= True¶ Is directory creation allowed.
-
can_rename
= True¶ Is file and directory renaming allowed.
-
allowed_extensions
= None¶ List of allowed extensions for uploads, in lower case.
Example:
class MyAdmin(FileAdmin): allowed_extensions = ('swf', 'jpg', 'gif', 'png')
-
editable_extensions
= ()¶ List of editable extensions, in lower case.
Example:
class MyAdmin(FileAdmin): editable_extensions = ('md', 'html', 'txt')
-
list_template
= 'admin/file/list.html'¶ File list template
-
upload_template
= 'admin/file/form.html'¶ File upload template
-
mkdir_template
= 'admin/file/form.html'¶ Directory creation (mkdir) template
-
rename_template
= 'admin/file/rename.html'¶ Rename template
-
edit_template
= 'admin/file/edit.html'¶ Edit template
-
can_download
= True¶ Is file download allowed.
-
delete_form
()[source]¶ Instantiate file delete form and return it.
Override to implement custom behavior.
-
edit_form
()[source]¶ Instantiate file editing form and return it.
Override to implement custom behavior.
-
edit_template
= 'admin/file/edit.html' Edit template
-
form_base_class
¶ Base form class. Will be used to create the upload, rename, edit, and delete form.
Allows enabling CSRF validation and useful if you want to have custom contructor or override some fields.
Example:
class MyBaseForm(Form): def do_something(self): pass class MyAdmin(FileAdmin): form_base_class = MyBaseForm
alias of
BaseForm
-
get_base_path
()[source]¶ Return base path. Override to customize behavior (per-user directories, etc)
-
get_delete_form
()[source]¶ Create form class for model delete view.
Override to implement customized behavior.
-
get_edit_form
()[source]¶ Create form class for file editing view.
Override to implement customized behavior.
-
get_name_form
()[source]¶ Create form class for renaming and mkdir views.
Override to implement customized behavior.
-
get_upload_form
()[source]¶ Upload form class for file upload view.
Override to implement customized behavior.
-
index
(*args, **kwargs)[source]¶ Index view method
Parameters: path – Optional directory path. If not provided, will use the base directory
-
is_accessible_path
(path)[source]¶ Verify if the provided path is accessible for the current user.
Override to customize behavior.
Parameters: path – Relative path to the root
-
is_file_allowed
(filename)[source]¶ Verify if file can be uploaded.
Override to customize behavior.
Parameters: filename – Source file name
-
is_file_editable
(filename)[source]¶ Determine if the file can be edited.
Override to customize behavior.
Parameters: filename – Source file name
-
is_in_folder
(base_path, directory)[source]¶ Verify that directory is in base_path folder
Parameters: - base_path – Base directory path
- directory – Directory path to check
-
mkdir
(*args, **kwargs)[source]¶ Directory creation view method
Parameters: path – Optional directory path. If not provided, will use the base directory
-
name_form
()[source]¶ Instantiate form used in rename and mkdir then return it.
Override to implement custom behavior.
-
on_directory_delete
(full_path, dir_name)[source]¶ Perform some actions after a directory has successfully been deleted.
Called from delete method
By default do nothing.
-
on_edit_file
(full_path, path)[source]¶ Perform some actions after a file has been successfully changed.
Called from edit method
By default do nothing.
-
on_file_delete
(full_path, filename)[source]¶ Perform some actions after a file has successfully been deleted.
Called from delete method
By default do nothing.
-
on_file_upload
(directory, path, filename)[source]¶ Perform some actions after a file has been successfully uploaded.
Called from upload method
By default do nothing.
-
on_mkdir
(parent_dir, dir_name)[source]¶ Perform some actions after a directory has successfully been created.
Called from mkdir method
By default do nothing.
-
on_rename
(full_path, dir_base, filename)[source]¶ Perform some actions after a file or directory has been renamed.
Called from rename method
By default do nothing.
-
save_file
(path, file_data)[source]¶ Save uploaded file to the disk
Parameters: - path – Path to save to
- file_data – Werkzeug FileStorage object
-
upload
(*args, **kwargs)[source]¶ Upload view method
Parameters: path – Optional directory path. If not provided, will use the base directory
Changelog¶
1.2.0¶
- Codebase was migrated to Flask-Admin GitHub organization
- Automatically inject Flask-WTF CSRF token to internal Flask-Admin forms
- MapBox v4 support for GeoAlchemy
- Updated translations with help of CrowdIn
- Show warning if field was ignored in form rendering rules
- Simple AppEngine backend
- Optional support for Font Awesome in templates and menus
- Bug fixes
1.1.0¶
Mostly bug fix release. Highlights:
- Inline model editing on the list page
- FileAdmin refactoring and fixes
- FileUploadField and ImageUploadField will work with Required() validator
- Bug fixes
1.0.9¶
Highlights:
- Bootstrap 3 support
- WTForms 2.x support
- Updated DateTime picker
- SQLAlchemy backend: support for complex sortables, ability to search for related models, model inheritance support
- Customizable URL generation logic for all views
- New generic filter types: in list, empty, date range
- Added the
geoa
contrib module, for working with geoalchemy2 - Portugese translation
- Lots of bug fixes
1.0.8¶
Highlights:
- Cleaned up documentation, many thanks to Petrus Janse van Rensburg.
- More flexible menu system, ability to add links to menus
- Human-readable filter URLs
- Callable filter options
- EmailField filter
- Simple accessibility fixes
- InlineFormField now accepts widget_args and form_rules arguments
- Support for newer wtforms versions
- form_rules property that affects both create and edit forms
- Lots of bugfixes
Renamed Columns¶
Starting from version 1.0.4, Flask-Admin uses different configuration property names.
Please update your sources as support for old property names will be removed in future Flask-Admin versions.
Old Name | New name |
list_columns | column_list |
excluded_list_columns | column_exclude_list |
list_formatters | column_formatters |
list_type_formatters | column_type_formatters |
rename_columns | column_labels |
sortable_columns | column_sortable_list |
searchable_columns | column_searchable_list |
list_display_pk | column_display_pk |
auto_select_related | column_auto_select_related |
list_select_related | column_select_related_list |
list_display_all_relations | column_display_all_relations |
excluded_form_columns | form_excluded_columns |
disallowed_actions | action_disallowed_list |