Using standard app factory pattern problematic with Flask-Admin's way of using blueprints
See original GitHub issueThe 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:
- Created 8 years ago
- Reactions:1
- Comments:16 (12 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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
my create_app function has this in it, after
app
has been createdand 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.
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.
It work out in this way. just for your reference.