mirror of
https://github.com/fastapi-admin/fastapi-admin.git
synced 2026-03-13 10:32:25 +08:00
Add custom filters
This commit is contained in:
@@ -8,6 +8,7 @@ from tortoise import Model
|
||||
from . import enums
|
||||
from .common import get_all_models, import_obj, pwd_context
|
||||
from .exceptions import exception_handler
|
||||
from .filters import SearchFilter
|
||||
from .models import AbstractAdminLog, AbstractPermission, AbstractRole, AbstractUser
|
||||
from .schemas import LoginIn
|
||||
from .shortcuts import get_object_or_404
|
||||
@@ -244,6 +245,11 @@ class AdminApp(FastAPI):
|
||||
sort_fields = menu.sort_fields
|
||||
fields = {}
|
||||
pk = name = pk_field.get("name")
|
||||
# CustomSearchFilters
|
||||
for search_filter in filter(
|
||||
lambda x: type(x).__name__ == "type" and issubclass(x, SearchFilter), search_fields
|
||||
):
|
||||
search_fields_ret[search_filter.get_name()] = await search_filter.get_field()
|
||||
if not exclude_pk and not self._exclude_field(resource, name):
|
||||
field = Field(
|
||||
label=pk_field.get("name").title(),
|
||||
|
||||
36
fastapi_admin/filters.py
Normal file
36
fastapi_admin/filters.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from typing import Any
|
||||
|
||||
from tortoise import QuerySet
|
||||
|
||||
from fastapi_admin.site import Field
|
||||
|
||||
_search_filters = {}
|
||||
|
||||
|
||||
class Filter:
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset: QuerySet) -> QuerySet:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class SearchFilter:
|
||||
@classmethod
|
||||
def get_queryset(cls, queryset: QuerySet, option: Any) -> QuerySet:
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
async def get_field(cls) -> Field:
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def get_name(cls) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def register_filter(cls: SearchFilter):
|
||||
_search_filters[cls.get_name()] = cls
|
||||
return cls
|
||||
|
||||
|
||||
def get_filter_by_name(name: str):
|
||||
return _search_filters.get(name)
|
||||
@@ -27,6 +27,7 @@ from ..depends import (
|
||||
update_checker,
|
||||
)
|
||||
from ..factory import app
|
||||
from ..filters import get_filter_by_name
|
||||
from ..responses import GetManyOut
|
||||
from ..schemas import BulkIn
|
||||
from ..shortcuts import get_object_or_404
|
||||
@@ -83,8 +84,15 @@ async def get_resource(
|
||||
):
|
||||
menu = app.model_menu_mapping[resource]
|
||||
qs = model.all()
|
||||
for filter_ in menu.custom_filters:
|
||||
qs = filter_.get_queryset(qs)
|
||||
if query.where:
|
||||
qs = qs.filter(**query.where)
|
||||
for name, value in query.where.items():
|
||||
filter_cls = get_filter_by_name(name)
|
||||
if filter_cls:
|
||||
qs = filter_cls.get_queryset(qs, value)
|
||||
else:
|
||||
qs = qs.filter(**{name: value})
|
||||
sort = query.sort
|
||||
for k, v in sort.items():
|
||||
if k in menu.sort_fields:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
from typing import Dict, List, Optional, Tuple, Type, Union
|
||||
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
|
||||
@@ -19,7 +19,7 @@ class Menu(BaseModel):
|
||||
# raw id fields
|
||||
raw_id_fields: Optional[Tuple[str, ...]] = tuple()
|
||||
# searchable fields
|
||||
search_fields: Optional[Tuple[str, ...]] = tuple()
|
||||
search_fields = tuple()
|
||||
# sortable fields
|
||||
sort_fields: Optional[Tuple[str, ...]] = tuple()
|
||||
# define field type,like select,radiolist,text,date
|
||||
@@ -31,6 +31,7 @@ class Menu(BaseModel):
|
||||
import_: bool = False
|
||||
actions: Optional[Dict]
|
||||
bulk_actions: List[Dict] = [{"value": "delete", "text": "delete_all"}]
|
||||
custom_filters: List = []
|
||||
|
||||
|
||||
Menu.update_forward_refs()
|
||||
|
||||
Reference in New Issue
Block a user