Wrong dashboard while adding flask-admin to project

倖福魔咒の 提交于 2019-12-04 02:55:02

You should be initializing Admin and registering views and blueprints inside create_app. Check if this works for you.

# app factory
def 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:

  1. Change the current blueprint name in the repo to something different from admin, since flask-admin clashes with it. (Reading from your github issue it seems the are a lot of hardcoded internals for admin.static, which makes changing the current admin blueprint easier.

the anatomy of a Blueprint is kinda like this

# app/myblueprint/__init__.py
from flask import Blueprint

# a random blueprint
myblueprint = 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_blueprint
app.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

  1. flask-admin works based in views, and the pattern to generate admin views is by importing them and passing an url parameter that gets appended to the /admin endpoint (where flask-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 a model and a db.session object.
    • BaseView which you use to extend a generic view inside the admin blueprint used by flask-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.py
from flask_admin import BaseView, expose

class 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 forms
from .modelviews import DBView
admin.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.

Use url instead of endpoint

adm = Admin(name='test',url='/db')
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!