Home > Back-end >  Flask-Admin: add filter for parent's field
Flask-Admin: add filter for parent's field

Time:08-07

I need to apply a filter based on a parent's field, i.e., I need to filter by Driver's name (parent) in the model view for the Shift model (child). These are my models:

import datetime

from sqlalchemy import Integer, DATE, ForeignKey, Column, String
from sqlalchemy.orm import registry, declarative_mixin, declared_attr


mapper_registry = registry()

@declarative_mixin
class Basic:
    @declared_attr
    def __sa_dataclass_metadata_key__(cls):
        return "sa"

    @declared_attr
    def __tablename__(cls):
        return snakecase(cls.__name__)


@mapper_registry.mapped
@dataclass
class Driver(Basic):  # parent
    id: int = field(init=False, metadata=dict(sa=Column(Integer, autoincrement=True, unique=True, primary_key=True, nullable=False)))
    name: str = field(metadata=dict(Column(String(255), nullable=False)))


@mapper_registry.mapped
@dataclass
class Shift(Basic):  # child
    id: int = field(init=False, metadata=dict(sa=Column(Integer, autoincrement=True, unique=True, primary_key=True, nullable=False)))
    date: datetime.date = field(metadata=dict(sa=Column(DATE, nullable=False)))
    driver_id: int | None = field(metadata=dict(sa=Column(Integer, ForeignKey('driver.id'), nullable=True)))
    
    driver: Driver | None = field(metadata=dict(sa=lambda: relationship('Driver', lazy=False)))

This is my model view for the Shift model:

from flask_admin.contrib.sqla import ModelView

class ShiftModelView(ModelView):
    """ModelView to manage Shift model."""

    form_columns = ["id", "date"]
    form_widget_args = {"id": {"disabled": True}}
    column_list = [
        "id",
        "date",
    ]
    column_searchable_list = ["id", "date"]

I need to apply a filter by Driver's name in my model view ShiftModelView. I was thinking of adding a custom filter, but is there an easier way to achieve this?

CodePudding user response:

This can be achieved by adding "driver.name" (parent class) to the model view's column_filters:

from flask_admin.contrib.sqla import ModelView

class ShiftModelView(ModelView): """ModelView to manage Shift model."""

...
column_filters = ["driver.name"]
...

Notice that driver references the relationship of Driver in Shift, and the . (dot operator) access the field in the parent class.

  • Related