Commit 91a2d3bd authored by Serge S. Koval's avatar Serge S. Koval

More documentation, version bump

parent 02b936b6
......@@ -10,20 +10,16 @@ Introduction
This is library for building adminstrative interface on top of Flask framework.
Instead of providing simple scaffolding for the SQLAlchemy models, Flask-Admin
Instead of providing simple scaffolding for the database models, Flask-Admin
provides tools that can be used to build adminstrative interface of any complexity,
using consistent look and feel.
Small example (Flask initialization omitted)::
Flask-Admin comes with following batteries out of the box:
app = Flask(__name__)
admin = Admin()
admin.add_view(ModelView(User, db.session))
admin.add_view(GalleryManager(name='Photos', category='Cats'))
admin.init_app(app)
If you're looking for 0.x version of the Flask-Admin written by Andy Wilson, check `here <http://github.com/wilsaj/flask-admin-old>`_.
- SQLAlchemy model scaffolding
- MongoEngine model scaffolding
- Peewee model scaffolding
- File admin
Documentation
-------------
......
......@@ -11,9 +11,8 @@
- Change boolean filter to True/False instead of Yes/No
- Ability to sort by fields that are not visible?
- List display callables?
- SQLA Model Admin
- Postprocess sort columns - do not resolve to attributes in runtime
- WYSIWYG editor support?
- MongoEngine
- EmbeddedDocument customization
- File admin
- Header title
- File size restriction
......
......@@ -10,5 +10,6 @@ API
mod_tools
mod_contrib_sqlamodel
mod_contrib_mongoengine
mod_contrib_peeweemodel
mod_contrib_fileadmin
\ No newline at end of file
``flask.ext.admin.contrib.mongoengine``
=======================================
MongoEngine model backend implementation.
.. automodule:: flask.ext.admin.contrib.mongoengine
.. autoclass:: ModelView
:members:
:inherited-members:
:exclude-members: hide_backrefs, auto_select_related, list_select_related,
searchable_columns, filter_converter, fast_mass_delete,
inline_model_form_converter, inline_models, model_form_conveter,
list_type_formatters
Class inherits configuration options from :class:`~flask.ext.admin.model.BaseModelView` and they're not displayed here.
.. autoattribute:: searchable_columns
.. autoattribute:: filter_converter
.. autoattribute:: model_form_converter
.. autoattribute:: list_type_formatters
\ No newline at end of file
......@@ -19,5 +19,4 @@ Peewee model backend implementation.
.. autoattribute:: fast_mass_delete
.. autoattribute:: inline_models
.. autoattribute:: inline_model_form_converter
.. autoattribute:: inline_models
.. autoattribute:: model_form_conveter
.. autoattribute:: model_form_converter
Database backends
=================
.. toctree::
:maxdepth: 2
db_sqla
db_mongoengine
db_peewee
MongoEngine backend
===================
Features:
- MongoEngine 0.7+ support;
- Paging, sorting, filters, etc;
- Inline editing of related models;
In order to use MongoEngine integration, you need to install `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:
- There's no way to configure EmbeddedDocument display options
- Search functionality can't split query into multiple terms
For more documentation, check :doc:`api/mod_contrib_mongoengine` documentation.
Peewee backend
==============
Flask-Admin provides Peewee ORM backend.
Peewee is a small ORM and some people showed interest in
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 :doc:`api/mod_contrib_peeweemodel` documentation.
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.
For more documentation, check :doc:`api/mod_contrib_sqlamodel` documentation.
......@@ -8,6 +8,7 @@ Flask-Admin is simple and extensible administrative interface framework for `Fla
quickstart
templates
db
model_guidelines
api/index
changelog
......
......@@ -292,9 +292,11 @@ Check :mod:`flask.ext.admin.contrib.fileadmin` documentation on how to do it.
Examples
--------
Flask-Admin comes with four samples:
Flask-Admin comes with few examples:
- `Simple administrative interface <https://github.com/MrJoes/Flask-Admin/tree/master/examples/simple>`_ with custom administrative views
- `SQLAlchemy model example <https://github.com/MrJoes/Flask-Admin/tree/master/examples/sqla>`_
- `Flask-Login integration example <https://github.com/MrJoes/Flask-Admin/tree/master/examples/auth>`_
- `File management interface <https://github.com/MrJoes/Flask-Admin/tree/master/examples/file>`_
- `Peewee model example <https://github.com/MrJoes/Flask-Admin/tree/master/examples/peewee>`_
- `MongoEngine model example <https://github.com/MrJoes/Flask-Admin/tree/master/examples/mongoengine>`_
......@@ -75,10 +75,6 @@ if __name__ == '__main__':
# Create admin
admin = admin.Admin(app, 'Simple Models')
#p = Post.objects[0]
#p.inner.append(Comment(name='12345'))
#p.save()
# Add views
admin.add_view(UserView(User))
admin.add_view(ModelView(Todo))
......
__version__ = '1.0.3'
__version__ = '1.0.4'
__author__ = 'Serge S. Koval'
__email__ = 'serge.koval+github@gmail.com'
......
......@@ -2,6 +2,9 @@ from wtforms.fields import FormField
class ModelFormField(FormField):
"""
Customized ModelFormField for MongoEngine EmbeddedDocuments.
"""
def __init__(self, model, *args, **kwargs):
super(ModelFormField, self).__init__(*args, **kwargs)
......
......@@ -99,8 +99,6 @@ class FilterConverter(filters.BaseFilterConverter):
numeric = (FilterEqual, FilterNotEqual, FilterGreater, FilterSmaller)
def convert(self, type_name, column, name):
#print type_name, column, name
if type_name in self.converters:
return self.converters[type_name](column, name)
......
from mongoengine import ReferenceField
from wtforms import fields as f
from flask.ext.mongoengine.wtf import orm, fields
from flask.ext.admin import form
......@@ -12,6 +10,12 @@ from .fields import ModelFormField
class CustomModelConverter(orm.ModelConverter):
"""
Customized MongoEngine form conversion class.
Injects various Flask-Admin widgets and handles lists with
customized InlineFieldList field.
"""
@orm.converts('DateTimeField')
def conv_DateTime(self, model, field, kwargs):
kwargs['widget'] = form.DateTimePickerWidget()
......@@ -37,7 +41,6 @@ class CustomModelConverter(orm.ModelConverter):
@orm.converts('EmbeddedDocumentField')
def conv_EmbeddedDocument(self, model, field, kwargs):
# TODO: Fix me
kwargs = {
'validators': [],
'filters': [],
......
def parse_like_term(term):
"""
Parse search term into (operation, term) tuple
:param term:
Search term
"""
if term.startswith('^'):
return 'startswith', term[1:]
elif term.startswith('='):
......
......@@ -31,6 +31,10 @@ SORTABLE_FIELDS = set((
class ModelView(BaseModelView):
"""
MongoEngine model scaffolding.
"""
column_filters = None
"""
Collection of the column filters.
......@@ -72,25 +76,27 @@ class ModelView(BaseModelView):
Override this attribute to use non-default converter.
"""
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 SQLAlchemy 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.
"""
list_type_formatters = MONGOENGINE_FORMATTERS
"""
Customized list formatters for MongoEngine backend
Customized type formatters for MongoEngine backend
"""
def __init__(self, model, name=None,
category=None, endpoint=None, url=None):
"""
Constructor
:param model:
Model class
:param name:
Display name
:param category:
Display category
:param endpoint:
Endpoint
:param url:
Custom URL
"""
self._search_fields = []
super(ModelView, self).__init__(model, name, category, endpoint, url)
......@@ -99,7 +105,10 @@ class ModelView(BaseModelView):
def _get_model_fields(self, model=None):
"""
Return list of model field_args
Inspect model and return list of model fields
:param model:
Model to inspect
"""
if model is None:
model = self.model
......@@ -111,14 +120,21 @@ class ModelView(BaseModelView):
return 'id'
def get_pk_value(self, model):
"""
Return primary key value from the model instance
:param model:
Model instance
"""
return model.pk
def scaffold_list_columns(self):
"""
Scaffold list columns
"""
columns = []
for n, f in self._get_model_fields():
#import pdb; pdb.set_trace()
# Filter by name
if (self.excluded_list_columns and
n in self.excluded_list_columns):
......@@ -138,6 +154,9 @@ class ModelView(BaseModelView):
return columns
def scaffold_sortable_columns(self):
"""
Return sortable columns dictionary (name, field)
"""
columns = {}
for n, f in self._get_model_fields():
......@@ -148,6 +167,9 @@ class ModelView(BaseModelView):
return columns
def init_search(self):
"""
Init search
"""
if self.searchable_columns:
for p in self.searchable_columns:
if isinstance(p, basestring):
......@@ -168,6 +190,12 @@ class ModelView(BaseModelView):
return bool(self._search_fields)
def scaffold_filters(self, name):
"""
Return filter object(s) for the field
:param name:
Either field name or field instance
"""
if isinstance(name, basestring):
attr = self.model._fields.get(name)
else:
......@@ -194,6 +222,12 @@ class ModelView(BaseModelView):
return flt
def is_valid_filter(self, filter):
"""
Validate if it is valid MongoEngine filter
:param filter:
Filter object
"""
return isinstance(filter, BaseMongoEngineFilter)
def scaffold_form(self):
......@@ -209,7 +243,22 @@ class ModelView(BaseModelView):
def get_list(self, page, sort_column, sort_desc, search, filters,
execute=True):
"""
Get list of objects from MongoEngine
:param page:
Page number
:param sort_column:
Sort column
:param sort_desc:
Sort descending
:param search:
Search criteria
:param filters:
List of applied fiters
:param execute:
Run query immediately or not
"""
query = self.model.objects
# Filters
......@@ -258,9 +307,21 @@ class ModelView(BaseModelView):
return count, query
def get_one(self, id):
"""
Return single model instance by ID
:param id:
Model ID
"""
return self.model.objects.with_id(id)
def create_model(self, form):
"""
Create model helper
:param form:
Form instance
"""
try:
model = self.model()
form.populate_obj(model)
......@@ -274,6 +335,14 @@ class ModelView(BaseModelView):
return False
def update_model(self, form, model):
"""
Update model helper
:param form:
Form instance
:param model:
Model instance to update
"""
try:
form.populate_obj(model)
self.on_model_change(form, model)
......@@ -286,6 +355,12 @@ class ModelView(BaseModelView):
return False
def delete_model(self, model):
"""
Delete model helper
:param model:
Model instance
"""
try:
self.on_model_delete(model)
model.delete()
......
......@@ -73,7 +73,7 @@ class ModelView(BaseModelView):
"""
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 SQLAlchemy chance to manually cleanup any dependencies (many-to-many
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment