Commit b1702039 authored by Serge S. Koval's avatar Serge S. Koval

Added support for multiple Admin() instanced for one Flask application. Fixes #55

parent bd1de11a
try: try:
from .helpers import get_current_view
from flask.ext.babel import Domain from flask.ext.babel import Domain
from flask.ext.admin import translations from flask.ext.admin import translations
...@@ -8,9 +10,12 @@ try: ...@@ -8,9 +10,12 @@ try:
super(CustomDomain, self).__init__(translations.__path__[0], domain='admin') super(CustomDomain, self).__init__(translations.__path__[0], domain='admin')
def get_translations_path(self, ctx): def get_translations_path(self, ctx):
dirname = ctx.app.extensions['admin'].translations_path view = get_current_view()
if dirname is not None:
return dirname if view is not None:
dirname = view.admin.translations_path
if dirname is not None:
return dirname
return super(CustomDomain, self).get_translations_path(ctx) return super(CustomDomain, self).get_translations_path(ctx)
......
...@@ -5,6 +5,8 @@ from flask import Blueprint, render_template, url_for, abort ...@@ -5,6 +5,8 @@ from flask import Blueprint, render_template, url_for, abort
from flask.ext.admin import babel from flask.ext.admin import babel
from .helpers import set_current_view
def expose(url='/', methods=('GET',)): def expose(url='/', methods=('GET',)):
""" """
...@@ -28,6 +30,10 @@ def expose(url='/', methods=('GET',)): ...@@ -28,6 +30,10 @@ def expose(url='/', methods=('GET',)):
def _wrap_view(f): def _wrap_view(f):
@wraps(f) @wraps(f)
def inner(self, **kwargs): def inner(self, **kwargs):
# Store current admin view
set_current_view(self)
# Check if administrative piece is accessible
h = self._handle_view(f.__name__, **kwargs) h = self._handle_view(f.__name__, **kwargs)
if h is not None: if h is not None:
...@@ -302,7 +308,8 @@ class Admin(object): ...@@ -302,7 +308,8 @@ class Admin(object):
def __init__(self, app=None, name=None, def __init__(self, app=None, name=None,
url=None, subdomain=None, url=None, subdomain=None,
index_view=None, index_view=None,
translations_path=None): translations_path=None,
endpoint=None):
""" """
Constructor. Constructor.
...@@ -319,6 +326,9 @@ class Admin(object): ...@@ -319,6 +326,9 @@ class Admin(object):
:param translations_path: :param translations_path:
Location of the translation message catalogs. By default will use translations Location of the translation message catalogs. By default will use translations
shipped with the Flask-Admin. shipped with the Flask-Admin.
:param endpoint:
Base endpoint name for index view. If you use multiple instances of `Admin` class with
one Flask application, you have to set unique endpoint name for each instance.
""" """
self.app = app self.app = app
...@@ -337,21 +347,24 @@ class Admin(object): ...@@ -337,21 +347,24 @@ class Admin(object):
self.url = url self.url = url
self.subdomain = subdomain self.subdomain = subdomain
self.endpoint = endpoint
# Localizations # Localizations
self.locale_selector_func = None self.locale_selector_func = None
# Register with application
if app:
self._init_extension()
# Index view # Index view
if index_view is None: if index_view is None:
index_view = AdminIndexView(url=self.url) index_view = AdminIndexView(endpoint=self.endpoint, url=self.url)
self.index_view = index_view self.index_view = index_view
# Add predefined index view # Add predefined index view
self.add_view(index_view) self.add_view(index_view)
if app:
self._init_extension()
def add_view(self, view): def add_view(self, view):
""" """
Add view to the collection. Add view to the collection.
...@@ -429,20 +442,30 @@ class Admin(object): ...@@ -429,20 +442,30 @@ class Admin(object):
self.app = app self.app = app
self._init_extension()
# Register views
for view in self._views: for view in self._views:
app.register_blueprint(view.create_blueprint(self)) app.register_blueprint(view.create_blueprint(self))
self._add_view_to_menu(view) self._add_view_to_menu(view)
self._init_extension()
def _init_extension(self): def _init_extension(self):
if not hasattr(self.app, 'extensions'): if not hasattr(self.app, 'extensions'):
self.app.extensions = dict() self.app.extensions = dict()
if 'admin' in self.app.extensions: admins = self.app.extensions.get('admin', [])
raise Exception('Can not have more than one instance of the Admin class associated with Flask application')
for p in admins:
if p.endpoint == self.endpoint:
raise Exception('Cannot have two Admin() instances with same'
' endpoint name.')
if p.url == self.url and p.subdomain == self.subdomain:
raise Exception('Cannot assign two Admin() instances with same'
' URL and subdomain to the same application.')
self.app.extensions['admin'] = self admins.append(self)
self.app.extensions['admin'] = admins
def menu(self): def menu(self):
""" """
......
from flask import g
def set_current_view(view):
g._admin_view = view
def get_current_view():
return getattr(g, '_admin_view', None)
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