titpoettt
titpoettt

Reputation: 81

Override default Model View

How can I override the Model View so by default all Model Views have exact same settings which I override?

For example: I have 5 model views linked to some db models which are all custom,but I want all these 5 to have some default settings so I won't have to write code for each view in the ModelView class.

Upvotes: 0

Views: 793

Answers (1)

pjcunningham
pjcunningham

Reputation: 8046

Use inheritance:

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

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

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

A simple one file example below.

Class BaseView turns on can_view_details and formats the description column in upper case.

Notice the difference between ProductView, which inherits from BaseView, and ProductNotInheritedView which inherits directly from ModelView.

Note the code uses the Faker library to generate random data.

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)

Upvotes: 1

Related Questions