覆盖默认模型视图

Override default Model View

如何覆盖模型视图,以便默认情况下所有模型视图都具有我覆盖的完全相同的设置?

例如: 我有 5 个模型视图链接到一些都是自定义的数据库模型,但我希望所有这 5 个都有一些默认设置,这样我就不必为模型视图中的每个视图编写代码 class.

使用继承:

class BaseView(ModelView):
    #  Add common functionality here
    pass

class ProductView(BaseView):
    #  Add specific functionality here
    pass

class CategoryView(BaseView):
    #  Add specific functionality here
    pass

下面是一个简单的文件示例。

Class BaseView 打开 can_view_details 并将 description 列格式化为大写。

请注意继承自 BaseViewProductView 和直接继承自 ModelViewProductNotInheritedView 之间的区别。

注意代码使用 Faker 库生成随机数据。

from flask import Flask
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy
from faker import Faker
from flask_admin import Admin

app = Flask(__name__)

# Create in-memory database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


# Flask views
@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'


class Supplier(db.Model):
    __tablename__ = 'supplier'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.Unicode(100), nullable=False)
    description = db.Column(db.UnicodeText(), nullable=True)

    products = db.relationship("Product", back_populates="supplier")

    def __str__(self):
        return unicode(self).encode('utf-8')

    def __unicode__(self):
        return self.name


class Product(db.Model):
    __tablename__ = 'product'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.Unicode(100), nullable=False)
    code = db.Column(db.Unicode(32), nullable=False)
    description = db.Column(db.UnicodeText(), nullable=True)

    supplier_id = db.Column(db.Integer, db.ForeignKey('supplier.id'), index=True, nullable=False)
    supplier = db.relationship(Supplier, back_populates='products')

    def __str__(self):
        return unicode(self).encode('utf-8')

    def __unicode__(self):
        return self.name


class BaseView(ModelView):
    can_view_details = True

    column_formatters = {
        'description': lambda v, c, m, p: m.description.upper(),
    }


class SupplierView(BaseView):
    column_list = ('name', 'description', 'products')


class ProductView(BaseView):
    pass


class ProductNotInheritedView(ModelView):
    pass


admin = Admin(app, template_mode="bootstrap3")
admin.add_view(SupplierView(Supplier, db.session))
admin.add_view(ProductView(Product, db.session))
admin.add_view(
    ProductNotInheritedView(Product, db.session, name='Product Not Inherited', endpoint='product-not-inherited'))


@app.before_first_request
def build_sample_db():

    db.drop_all()
    db.create_all()

    fake = Faker()

    _suppliers = []
    for _ in range(20):
        _supplier = Supplier(
            name=fake.company(),
            description=fake.paragraph(nb_sentences=fake.random.randint(1, 10))
        )
        _suppliers.append(_supplier)
        for _ in range(fake.random.randint(1, 10)):
            _supplier.products.append(
                Product(
                    name=' '.join(fake.words(nb=fake.random.randint(1, 5))),
                    description=fake.paragraph(nb_sentences=fake.random.randint(1, 10)),
                    code=fake.isbn10(separator="-")
                )
            )

    db.session.add_all(_suppliers)

    db.session.commit()


if __name__ == '__main__':
    app.run(port=5000, debug=True)