Search code examples
pythonflaskflask-admin

how can i register a Flask-Admin BaseView as a module


How can I register a Flask-Admin BaseView as a module in my application? every time I run my app I get a blueprint collision error!

I also know about ModelView in Flask-Admin, but I want to separate models and views from each other.

init.py

from flask import Flask
import flask_admin as admin
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)


from views.user import user_view, UserView

admin = admin.Admin(app, name='Backend')
user_view.add_view(UserView)

db.create_all()

Package Folder Backend

├── __init__.py
├── models.py
├── static
├── templates
│   └── user
│       └── index.html
└── views
    ├── __init__.py
    └── user.py

models.py

from . import db


class UserModel(db.Model):
    '__tablename__' == "User"
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(100))
    last_name = db.Column(db.String(100))
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    # Required for administrative interface. For python 3 please use __str__ instead.
    def __unicode__(self):
        return self.username

user.py

from flask_admin import Admin, BaseView, expose
from Backend import app

user_view = Admin(app, name="User")


class UserView(BaseView):
    @expose('/')
    def index(self):
        return self.render('user/index.html')

Solution

  • So I answer my own question. it was just a fallacy.

    I just need to import the UserView as described here. And also need to import the package app in the view.

    So here is the relation between __init__.py and views/user.py.

    init.py

    from flask import Flask
    import flask_admin as admin
    from flask.ext.sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
    db = SQLAlchemy(app)
    
    
    from views.user import UserView
    
    admin = admin.Admin(app, name='Backend')
    admin.add_view(UserView(name="User"))
    
    db.create_all()
    

    views/user.py

    from Backend import app
    from flask_admin import BaseView, expose
    
    
    class UserView(BaseView):
        @expose('/')
        def index(self):
            return self.render('user/index.html')
    

    This part from Flask Documentaion: was interessting.

    Circular Imports:

    Every Python programmer hates them, and yet we just added some: circular imports (That’s when two modules depend on each other. In this case views.py depends on init.py). Be advised that this is a bad idea in general but here it is actually fine. The reason for this is that we are not actually using the views in init.py and just ensuring the module is imported and we are doing that at the bottom of the file.