question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using standard app factory pattern problematic with Flask-Admin's way of using blueprints

See original GitHub issue

The example below might not be a very good use of the app factory pattern, but imagine that you’re using sqla.ModelView instead. Then we would have to issue admin.add_view() within the create_app flow because we need to pass in the model and database session. Right now I use a workaround found in this SO thread. Is there some way that we could change Flask-Admin’s behavior so that we can follow Flask’s standard application factory workflow?

import flask
import flask_admin
import unittest


class MyAdminView(flask_admin.BaseView):
    @flask_admin.expose('/')
    def index(self):
        self.render('index.html')


admin = flask_admin.Admin()


def create_app():
    app = flask.Flask(__name__)
    admin.add_view(MyAdminView(name='myview1', endpoint='myview1'))
    admin.init_app(app)
    return app


class BlueprintCollisionTestCase(unittest.TestCase):

    def setUp(self):
        self.app = create_app()

    def test_1(self):
        assert 1 == 1

    def test_2(self):
        assert 1 == 1


if __name__ == '__main__':
    unittest.main()
$ python testflaskadmin.py
.F
======================================================================
FAIL: test_2 (__main__.BlueprintCollisionTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testflaskadmin.py", line 25, in setUp
    self.app = create_app()
  File "testflaskadmin.py", line 18, in create_app
    admin.add_view(MyAdminView(name='myview1', endpoint='myview1'))
  File "/Users/jacob/venvs/myvenv/lib/python3.4/site-packages/Flask_Admin-1.2.0-py3.4.egg/flask_admin/base.py", line 526, in add_view
    self.app.register_blueprint(view.create_blueprint(self))
  File "/Users/jacob/venvs/myvenv/lib/python3.4/site-packages/flask/app.py", line 62, in wrapper_func
    return f(self, *args, **kwargs)
  File "/Users/jacob/venvs/myvenv/lib/python3.4/site-packages/flask/app.py", line 885, in register_blueprint
    (blueprint, self.blueprints[blueprint.name], blueprint.name)
AssertionError: A blueprint's name collision occurred between <flask.blueprints.Blueprint object at 0x1018ebc18> and <flask.blueprints.Blueprint object at 0x1018eb2b0>.  Both share the same name "myview1".  Blueprints that are created on the fly need unique names.

----------------------------------------------------------------------
Ran 2 tests in 0.003s

FAILED (failures=1)

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:16 (12 by maintainers)

github_iconTop GitHub Comments

13reactions
drcongocommented, May 1, 2016

Thought I’d chip in with my solution to this issue, as I forget about it every time and I’ll only end up finding this through google again.

I have this function in admin/core.py

def init_admin(f_admin):
    f_admin.add_view(UserView(db.session, name="Users", endpoint="users"))
    [...]

my create_app function has this in it, after app has been created

    f_admin = Admin(
        app,
        name='Admin',
        index_view=CustomAdminIndexView(template='admin/dashboard.html')
    )

and then further on, in the create_app after all my other blueprints have been registered I call the init_admin function and pass it the f_admin object.

    init_admin(f_admin)

Weirdly, if I do the traditional init_app method everything seemed to work when running the site on the dev server, but I would get the blueprint name collisions when running my tests under pytest.

3reactions
miaohfcommented, Mar 2, 2019

It work out in this way. just for your reference.

#YourApp/init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin

db = SQLAlchemy()
admin = Admin(name='TuozhanOA', template_mode='bootstrap3')
def create_app(config_class=Config):
    app = Flask(name)
    app.config.from_object(Config)
    db.init_app(app)
    admin.init_app(app)
    from YourApp.main.routes import main
    app.register_blueprint(main)
    from YourApp.adminbp.routes import adminbp, user_datastore
    app.register_blueprint(adminbp)
    security = Security(app, user_datastore)
    return app

#YourApp/adminbp/routes.py
from flask import render_template, Blueprint
from YourApp.models import User, Role
from YourApp import db, admin
from flask_admin.contrib.sqla import ModelView
from wtforms.fields import PasswordField
from flask_admin.contrib.fileadmin import FileAdmin
import os.path as op

from flask_security import current_user, login_required, RoleMixin, Security, 
SQLAlchemyUserDatastore, UserMixin, utils

adminbp = Blueprint('adminbp', name)
admin.add_view(ModelView(User, db.session, category="Team"))
admin.add_view(ModelView(Role, db.session, category="Team"))

path = op.join(op.dirname(file), 'tuozhan')
admin.add_view(FileAdmin(path, '/static/tuozhan/', name='File Explore'))
Read more comments on GitHub >

github_iconTop Results From Across the Web

Flask-Security RecursionError with Application Factory method
Looks like you've been trying a few things. First - initialize security.init_app(app, user_datastore) - don't assign to _state.
Read more >
Demystifying Flask's “Application Factory”
Create a Flask app using the 'Application Factory' pattern. Learn what an application context is and how to build large-scale apps properly.
Read more >
Application Factories — Flask Documentation (2.2.x)
A common pattern is creating the application object when the blueprint is imported. But if you move the creation of this object into...
Read more >
How to set up a production-grade flask application using ...
My personal approach is to use two blueprints, auth and main . ... Using the application factory pattern method of configuring flask ...
Read more >
Structuring Large Applications in Flask with Blueprints and ...
However, when building a small or medium-scale app, the structure of such application might not be of immense importance, especially if using ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found