From 0a5f589c2d79264f82f1f8be24a32625bf516bf5 Mon Sep 17 00:00:00 2001 From: Torrent Date: Thu, 16 Oct 2025 19:47:12 +0200 Subject: [PATCH] filter using schema --- club/api.py | 35 +++++------------------------------ club/schemas.py | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/club/api.py b/club/api.py index 70dd4b40..c952ed2f 100644 --- a/club/api.py +++ b/club/api.py @@ -1,7 +1,5 @@ -from typing import Annotated, Optional - -from annotated_types import MinLen from django.db.models import Prefetch +from ninja import Query from ninja.security import SessionAuth from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.pagination import PageNumberPaginationExtra @@ -10,7 +8,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from api.auth import ApiKeyAuth from api.permissions import CanAccessLookup, HasPerm from club.models import Club, Membership -from club.schemas import ClubSchema, SimpleClubSchema +from club.schemas import ClubSchema, ClubSearchFilterSchema, SimpleClubSchema @api_controller("/club") @@ -25,33 +23,10 @@ class ClubController(ControllerBase): @paginate(PageNumberPaginationExtra, page_size=50) def search_club( self, - search: Annotated[Optional[str], MinLen(1), "filter by name"] = None, - club_id: Annotated[Optional[int], "filter by club id"] = None, - excluded_ids: Annotated[ - Optional[list[int]], "filter by excluded club ids" - ] = None, - is_active: Annotated[Optional[bool], "filter by club activity"] = None, - parent_id: Annotated[Optional[int], "filter by parent id"] = None, - parent_name: Annotated[ - Optional[str], MinLen(1), "filter by parent name" - ] = None, + filters: Query[ClubSearchFilterSchema], ): - queryset = Club.objects.all() - - if search: - queryset = queryset.filter(name__icontains=search) - if club_id: - queryset = queryset.filter(id=club_id) - if is_active: - queryset = queryset.filter(is_active=is_active) - if parent_name: - queryset = queryset.filter(parent__name__icontains=parent_name) - if parent_id: - queryset = queryset.filter(parent_id=parent_id) - if excluded_ids: - queryset = queryset.exclude(id__in=excluded_ids) - - return queryset.values() + clubs = Club.objects.all() + return filters.filter(clubs) @route.get( "/{int:club_id}", diff --git a/club/schemas.py b/club/schemas.py index b0601af8..9ba4d235 100644 --- a/club/schemas.py +++ b/club/schemas.py @@ -1,9 +1,24 @@ -from ninja import ModelSchema +from typing import Optional + +from django.db.models import Q +from ninja import Field, FilterSchema, ModelSchema from club.models import Club, Membership from core.schemas import SimpleUserSchema +class ClubSearchFilterSchema(FilterSchema): + search: Optional[str] = Field(None, q="name__icontains") + club_id: Optional[int] = Field(None, q="id") + is_active: Optional[bool] = None + parent_id: Optional[int] = None + parent_name: Optional[str] = Field(None, q="parent__name__icontains") + exclude_ids: Optional[list[int]] = None + + def filter_exclude_ids(self, value: list[int]): + return ~Q(id__in=value) + + class SimpleClubSchema(ModelSchema): class Meta: model = Club