Wrong dashboard while adding flask-admin to project
You should be initializing Admin
and registering views
and blueprints
inside create_app
. Check if this works for you.
# app factorydef create_app(config_name): # configure current app app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app) # wrap app with extensions ... # admin.init_app(app) does not work and flask-admin # should be instantiated inside create_app() # see https://github.com/flask-admin/flask-admin/issues/910#issuecomment-115003492 # for details admin = Admin(app, name='MyAPP') ... # import models from .models.user import User # more imports happening here # import flask-admin views to be used in the admin panel from .admin.views import MyView # register admin view forms admin.add_view(MyView(name='MyCustomView', endpoint='db')) # register blueprints # ... # implementation of the app factory pattern return app
EDIT:
What I believe is happening is that
- The app in the repo has already a blueprint named
admin
living in /admin - You want to implement
flask-admin
in the app, but it clashes with the existing blueprint
You can achieve this doing two things:
- Change the current
blueprint
name in the repo to something different fromadmin
, sinceflask-admin
clashes with it. (Reading from your github issue it seems the are a lot of hardcoded internals foradmin.static
, which makes changing the currentadmin
blueprint easier.
the anatomy of a Blueprint is kinda like this
# app/myblueprint/__init__.pyfrom flask import Blueprint# a random blueprintmyblueprint = Blueprint(name='mycustomblueprint', import_name=__name__, # name of the file static_folder='static', # a folder inside app/myblueprint/static template_folder='templates', # a folder inside app/myblueprint/templates static_url_path='/static', # this is what mycustomblueprint.static will point to, and if the name is admin it will be admin.static, thus colliding with flask-admin url_prefix='/myblueprintprefix', # this will be appended to each view inside your blueprint, i.e. a view '/foo' will get converted into '/myblueprintprefix/foo' in your url mappings subdomain=None, url_defaults=None, root_path=None)from . import views # import the views inside app/myblueprint/views.py
then, you import it inside create_app
as
from .myblueprint import myblueprint as my_blueprintapp.register_blueprint(my_blueprint) # notice I've defined url_prefix in the Blueprint definition. You can do it at registration time, it's up to you
tl;dr: change the admin
blueprint since it's clashing with flask-admin
flask-admin
works based in views, and the pattern to generate admin views is by importing them and passing anurl
parameter that gets appended to the/admin
endpoint (whereflask-admin
lives). In this case, you can think of two flavours (more but for the sake of the example it's okay)ModelView
, which you use to create custom CRUD views and takes both amodel
and adb.session
object.BaseView
which you use to extend a generic view inside theadmin
blueprint used byflask-admin
.
This means, if you want to render your own db.html
file inside the flask-admin
views, you have to do:
# app/modelviews/mycustomviews.pyfrom flask_admin import BaseView, exposeclass DBView(BaseView): # notice I'm using BaseView and not ModelView @expose('/') def index(self): return self.render('modelviews/db.html') # this file should live in app/templates/modelviews/db.html
and inside create_app
# register admin view formsfrom .modelviews import DBViewadmin.add_view(DBView(name='MyCustomView', endpoint='db')) # this will show up in your `flask-admin` main view as MyCustomView, and it will live in {host}/admin/db
You can also check in your url_map
parameter of the flask app in context that you have. You don't need this bit in your create_app
with app.app_context():m =app.url_map
I mentioned it because it could help you debug your views inside the python repl
. Import your app, and follow the gist I've provided. The url_map
should return something like a list of <Rules>
[<Rule '/admin/' (OPTIONS, HEAD, GET) -> admin.index>, <Rule '/admin/db' (OPTIONS, HEAD, GET) -> dbview.index>]
This way you can confirm that your view lives where it should. Hope this helps.