有几个问题。
Flask-Admin 使用视图的小写类名作为自动生成的蓝图名称。当您使用 UserView 两次时,您会遇到蓝图名称冲突。为了克服这个问题,您可以在实例化视图时指定 endpoint 名称,例如:
admin = Admin(app, template_mode="bootstrap3")
admin.add_view(TestView(StockTest, db.session, category='Stock', name='Test', endpoint='stock-test'))
admin.add_view(TestView(CommodityTest, db.session, category='Commodity', name='Test', endpoint='commodity-test'))
要获取视图的 url,您可以使用以下代码:
url_for('stock-test.index')
url_for('stock-test.edit')
url_for('commodity-test.index')
url_for('commodity-test.edit')
其次,如果你想使用Flask-Sqlalchemy的bind feature你应该在表模型上使用__bind_key__属性,例如:
class User(db.Model):
__bind_key__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
这是一个说明这两个概念的单个文件示例。在使用应用程序本身之前,您需要运行烧瓶命令 flask create-databases 和 flask populate-databases。请注意,我使用了一个 mixin 类 TestMixin 来定义模型列。
import click
from flask import Flask
from flask.cli import with_appcontext
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from faker import Faker
from sqlalchemy import Integer, Column, Text
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_BINDS'] = {
'stock': 'sqlite:///stock.db',
'commodity': 'sqlite:///commodity.db'
}
db.init_app(app)
class TestMixin(object):
id = Column(Integer, primary_key=True)
name = Column(Text(), unique=True, nullable=False)
class StockTest(db.Model, TestMixin):
__bind_key__ = 'stock'
class CommodityTest(db.Model, TestMixin):
__bind_key__ = 'commodity'
@click.command('create-databases')
@with_appcontext
def create_databases():
db.drop_all(bind=['stock', 'commodity'])
db.create_all(bind=['stock', 'commodity'])
@click.command('populate-databases')
@with_appcontext
def populate_databases():
_faker = Faker()
db.session.bulk_insert_mappings(StockTest, [{'name': _faker.name()} for _ in range(100)])
db.session.bulk_insert_mappings(CommodityTest, [{'name': _faker.name()} for _ in range(100)])
db.session.commit()
class TestView(ModelView):
pass
app.cli.add_command(create_databases)
app.cli.add_command(populate_databases)
admin = Admin(app, template_mode="bootstrap3")
admin.add_view(TestView(StockTest, db.session, category='Stock', name='Test', endpoint='stock-test'))
admin.add_view(TestView(CommodityTest, db.session, category='Commodity', name='Test', endpoint='commodity-test'))
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
if __name__ == '__main__':
app.run()