Flask-Admin如何在自动生成列列表中追加自定义列?
问题
我有一个包含数十个字段的SQLAlchemy模型,仅需在列表视图中添加计算属性site_name,不想手动列出所有自动生成的列再通过column_list添加该属性,希望Flask-Admin保持默认列生成逻辑并追加自定义列,同时可排除指定列(如capacity)。示例模型如下:
class Location(Base): __tablename__ = "locations" id: Mapped[int] = mapped_column(Sequence("location_id_seq", start=1, cycle=True), primary_key=True) name: Mapped[str] loc_tracking: Mapped[str] = mapped_column(default='Tagged') loc_type: Mapped[str] = mapped_column(default='FIFO') status: Mapped[str] = mapped_column(default='UnLocked') allocatable: Mapped[bool] = mapped_column(default=True) capacity: Mapped[int] = mapped_column(default=1) #need to put current volume here...yeah it's denormalized but will be used by putaway algs all the time #and it'll be too expensive to make it do the SQL every time. You'll also need to make sure add/remove inv #from core.inventory deals with updating this value. put_sequence: Mapped[int] = mapped_column(default=0) pick_sequence: Mapped[int] = mapped_column(default=0) stage_in_location_id: Mapped[int] = mapped_column(ForeignKey("locations.id"), nullable=True) stage_out_location_id: Mapped[int] = mapped_column(ForeignKey("locations.id"), nullable=True) zone_id: Mapped[int] = mapped_column(ForeignKey("zones.id")) zone: Mapped["Zone"] = relationship(back_populates="locations") @property def site_name(self) -> str: return self.zone.site_name
期望自定义ModelView时只需配置additional_columns和exclude_columns,无需手动列全量列:
class LocationView(ModelView): additional_columns = ('site_name',) exclude_columns = ('capacity',)
但不知需重写哪个方法实现该功能,同时希望表单列也能实现类似逻辑。
解决方案
列表视图实现
要在默认列生成逻辑基础上追加自定义列并排除指定列,需重写ModelView的get_list_columns方法,该方法负责生成列表视图的列集合,我们可以在默认结果上做修改:
from flask_admin.contrib.sqla import ModelView class LocationView(ModelView): additional_columns = ('site_name',) exclude_columns = ('capacity',) def get_list_columns(self): # 获取Flask-Admin默认生成的列 columns = super().get_list_columns() # 移除需要排除的列 for col in self.exclude_columns: if col in columns: columns.pop(col) # 添加自定义计算属性列,配置显示规则 for col in self.additional_columns: columns[col] = { 'label': col.replace('_', ' ').title(), 'formatter': lambda value, context, model, page: getattr(model, col) } return columns
表单视图实现
如果要在表单视图中实现类似逻辑(默认生成字段、排除指定字段、追加自定义字段),需重写get_form_columns方法,同时配置自定义字段的渲染规则:
from flask_admin.contrib.sqla import ModelView from flask_admin.form import rules from wtforms import StringField class LocationView(ModelView): additional_columns = ('site_name',) exclude_columns = ('capacity',) # 定义自定义表单字段的类型与属性 form_extra_fields = { 'site_name': StringField('Site Name', render_kw={'readonly': True}) } def get_form_columns(self): # 获取默认生成的表单列 columns = super().get_form_columns() # 过滤掉需要排除的列,同时处理嵌套字段组 filtered_columns = [] for col in columns: if isinstance(col, str): if col not in self.exclude_columns: filtered_columns.append(col) elif hasattr(col, 'fields'): # 处理FieldSet类型的嵌套字段 filtered_fields = [f for f in col.fields if f not in self.exclude_columns] filtered_columns.append(rules.FieldSet(filtered_fields, col.label)) else: filtered_columns.append(col) # 追加自定义列到表单 filtered_columns.extend(self.additional_columns) return filtered_columns def on_form_prefill(self, form, id): # 编辑页面预填充自定义计算属性的值 obj = self.get_one(id) form.site_name.data = obj.site_name
关键说明
- 列表视图中,
get_list_columns返回的是字典结构,键为列名,值为列的配置参数,我们通过修改这个字典实现列的增删。 - 表单视图中,
form_extra_fields用于定义自定义字段的类型,on_form_prefill负责在编辑场景下填充计算属性的值(因为是只读字段,无需保存)。
内容的提问来源于stack exchange,提问作者Robert Neville
相关产品推荐
相关产品推荐

