如何重写默认Model View,让所有Model View统一使用自定义默认配置?
嘿,这个问题太常见了,用继承抽离通用配置就完美解决了,不用再重复写一堆相同的代码。我给你详细拆解一下实现步骤:
1. 先定义你的通用基类ModelView
首先,你需要创建一个继承自原生ModelView的基类,把所有你想统一应用的配置、方法都写在这里——比如通用的权限控制、显示规则、表单设置等等,一次性搞定所有重复项。
举个实际的代码例子:
from flask_admin.contrib.sqla import ModelView from flask import redirect, url_for from flask_login import current_user # 这就是你的通用基类,所有业务视图都将继承它 class BaseModelView(ModelView): # 通用配置项,根据你的实际需求调整 column_display_pk = True # 统一显示主键ID can_delete = False # 全局禁用删除操作 column_hide_backrefs = False form_excluded_columns = ('created_at', 'updated_at') # 统一排除时间字段的编辑 # 通用权限控制逻辑 def is_accessible(self): # 这里写你的统一权限判断,比如仅管理员可访问 return current_user.is_authenticated and current_user.is_admin # 权限不足时的统一跳转 def inaccessible_callback(self, name, **kwargs): return redirect(url_for('auth.login', next=request.url))
2. 让业务视图继承这个基类
接下来,你的5个关联不同数据库模型的ModelView,只需要继承上面的BaseModelView,而不是直接继承原生的ModelView。如果某个视图需要特殊配置,直接在子类里覆盖基类的属性就行,完全不影响其他视图。
比如:
# 导入你的业务模型 from app.models import User, Post, Product, Order, Comment class UserView(BaseModelView): # User视图独有的配置,会覆盖基类的同名属性 column_list = ('id', 'username', 'email', 'created_at') column_searchable_list = ('username', 'email') class PostView(BaseModelView): # Post视图独有的配置 column_filters = ('category', 'publish_status') form_widget_args = { 'content': {'rows': 10} # 单独给内容框设置高度 } # 剩下的ProductView、OrderView、CommentView同理,只需要写独有的配置即可 class ProductView(BaseModelView): column_list = ('id', 'name', 'price', 'stock') class OrderView(BaseModelView): can_edit = False # 订单不允许编辑,覆盖基类的默认设置 class CommentView(BaseModelView): column_exclude_list = ('ip_address',)
3. 注册视图到Flask-Admin
最后一步,和原来一样注册各个视图就行,基类的配置会自动生效:
from flask_admin import Admin from app import app, db admin = Admin(app, name='后台管理系统', template_mode='bootstrap4') # 注册各个业务视图 admin.add_view(UserView(User, db.session)) admin.add_view(PostView(Post, db.session)) admin.add_view(ProductView(Product, db.session)) admin.add_view(OrderView(Order, db.session)) admin.add_view(CommentView(Comment, db.session))
额外小技巧:动态通用配置
如果你的通用配置需要根据不同模型做动态调整,可以在基类的__init__方法里处理。比如自动把模型的所有字段设为显示列:
class BaseModelView(ModelView): def __init__(self, model, session, **kwargs): # 动态设置显示列:自动包含模型的所有字段 self.column_list = [column.key for column in model.__table__.columns] # 调用父类的初始化方法 super().__init__(model, session, **kwargs)
这样一来,所有继承自BaseModelView的视图都会自动应用基类的配置,后期要修改通用规则的话,只需要改基类一处就行,维护起来超方便!
内容的提问来源于stack exchange,提问作者titpoettt
相关产品推荐
相关产品推荐

