dynamic mixin search for all apis

This commit is contained in:
2025-07-31 14:22:27 +03:30
parent b97a6c5893
commit a5b4d302ce
16 changed files with 129 additions and 197 deletions

View File

View File

@@ -0,0 +1,29 @@
from apps.core.services.filter.search import DynamicSearchService
class DynamicSearchMixin:
""" search query sets with introduced fields in view set """
def get_search_fields(self):
return getattr(self, "search_fields", [])
def get_date_field(self):
return getattr(self, "date_field", "create_date")
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset) # noqa
q = self.request.query_params.get("search") # noqa
start = self.request.query_params.get("start") # noqa
end = self.request.query_params.get("end") # noqa
search_fields = self.get_search_fields()
date_field = self.get_date_field()
return DynamicSearchService(
queryset=queryset,
query_string=q,
search_fields=search_fields,
start=start,
end=end,
date_field=date_field
).apply()

View File

View File

@@ -0,0 +1,40 @@
from django.db.models import Q
from django.db.models.functions import TruncDate
class DynamicSearchService:
def __init__(self, queryset, query_string: str = "", search_fields: list[str] = None,
start: str = None, end: str = None, date_field: str = "create_date"):
self.queryset = queryset
self.query = (query_string or "").strip()
self.fields = search_fields or []
self.start = start
self.end = end
self.date_field = date_field
def apply(self):
qs = self.queryset
if self.query and self.fields:
keywords = [k.strip() for k in self.query.split(",") if k.strip()]
q_obj = Q()
for kw in keywords:
for field in self.fields:
q_obj |= Q(**{f"{field}__icontains": kw}) # noqa
qs = qs.filter(q_obj).distinct()
if self.start or self.end:
qs = qs.annotate(date_only=TruncDate(self.date_field))
if self.start:
try:
qs = qs.filter(date_only__gte=self.start)
except ValueError:
pass # or log
if self.end:
try:
qs = qs.filter(date_only__lte=self.end)
except ValueError:
pass # or log
return qs