3
votes

I have a Flask 0.12.4 app and am using Flask-Admin.

I get this error intermittently when developing locally, and have just started seeing it in one of our public environments too.

AssertionError: A blueprint's name collision occurred between 
<flask.blueprints.Blueprint object at 0x7f5cd31f96d0> and 
<flask.blueprints.Blueprint object at 0x7f5cd33b0d90>.
Both share the same name "admin".
Blueprints that are created on the fly need unique names.

The steps to reproduce in my development environment are slightly odd:

  1. Break some of the admin config (e.g. change one of the strings relating to a column name in form_columns so it refers to a non-existent name)
  2. Refresh the browser to see the regular "unknown field" error
  3. Revert the change
  4. Refresh the browser again - you then see the blueprint error above

The line which is causing the error is this one:

# admin.py
admin = flask_admin.Admin(
    app, index_view=MyIndexView(), template_mode="bootstrap3"
)
2
Good edit, @halfer. I hadn't meant to imply urgency in terms of wanting an urgent answer, just some context as to why I only now bothered trying to fix this! But that wasn't obvious from my post, so your edit is a good one, thanks.Sam
Thanks Sam. I try to bear that distinction in mind when I edit (and it's probably why I didn't also comment) but some readers can misinterpret such remarks even if a question author was only referring to their own urgencies :-)halfer

2 Answers

1
votes

It seemed like the line in question was being called multiple times (although the file it's in is only imported in one place). I tried passing a custom endpoint in the Admin constructor and continued to get the same error but with the new endpoint name, which suggested that was the case.

This answer refers in passing to the same problem, and to the solution of using init_app rather than passing the app to the constructor.

Doing that, my code then looked like this, and the error went away:

# admin.py
# Notice I'm not passing app here any more.
admin = flask_admin.Admin(index_view=MyIndexView(), template_mode="bootstrap3")
# app.py
admin.init_app(app) # This line is new

I don't understand the detail of how the problem occurred or exactly why this solved it, so any further pointers welcome!

0
votes

to me help some idea from here. Flask-admin 1.5.3

# token.__init__.py  <-- token - my app
# endpoint - very important
from app.model import blueprint, Token
from db import db

blueprint = Blueprint("token", __name__, url_prefix='/token')

blueprint.custom_model_views = []
blueprint.custom_model_views += [ModelView(Token, db.session, endpoint='token-admin')]

# admin.__init__.py
def create_module(admin, app, **kwargs):
    admin.init_app(app)

    with app.app_context() as e:
        from app import token
        views = token.blueprint.custom_model_views
        for v in views:
            admin.add_view(v)

# root.__init__.py
flask_admin = Admin()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    from .token import create_module as token_create_module
    from .admin import create_module as admin_create_module

    token_create_module(app)
    admin_create_module(flask_admin, app)

    return app

check http://localhost:5000/admin/token-admin/