Implement search functionality improvements: optimize database queries, enhance service layer, and update frontend interactions

This commit is contained in:
pacnpal
2025-02-21 10:31:49 -05:00
parent 8c85b2afd4
commit 645a74a4c3
4 changed files with 262 additions and 78 deletions

View File

@@ -31,44 +31,66 @@ class ParkFilter(LocationFilterMixin, RatingFilterMixin, DateRangeFilterMixin, F
model = Park
fields = []
# Search field
search = CharFilter(method='filter_search')
# Search field with better description
search = CharFilter(
method='filter_search',
label=_("Search Parks"),
help_text=_("Search by park name, description, or location")
)
# Status filter
# Status filter with clearer label
status = ChoiceFilter(
field_name='status',
choices=Park._meta.get_field('status').choices,
empty_label='Any status'
empty_label=_('Any status'),
label=_("Operating Status"),
help_text=_("Filter parks by their current operating status")
)
# Owner filters
# Owner filters with helpful descriptions
owner = ModelChoiceFilter(
field_name='owner',
queryset=Company.objects.all(),
empty_label='Any company'
empty_label=_('Any company'),
label=_("Operating Company"),
help_text=_("Filter parks by their operating company")
)
has_owner = BooleanFilter(
method='filter_has_owner',
label=_("Company Status"),
help_text=_("Show parks with or without an operating company")
)
has_owner = BooleanFilter(method='filter_has_owner')
# Numeric filters
# Ride and attraction filters
min_rides = NumberFilter(
field_name='current_ride_count',
lookup_expr='gte',
validators=[validate_positive_integer]
validators=[validate_positive_integer],
label=_("Minimum Rides"),
help_text=_("Show parks with at least this many rides")
)
min_coasters = NumberFilter(
field_name='current_coaster_count',
lookup_expr='gte',
validators=[validate_positive_integer]
validators=[validate_positive_integer],
label=_("Minimum Roller Coasters"),
help_text=_("Show parks with at least this many roller coasters")
)
# Size filter
min_size = NumberFilter(
field_name='size_acres',
lookup_expr='gte',
validators=[validate_positive_integer]
validators=[validate_positive_integer],
label=_("Minimum Size (acres)"),
help_text=_("Show parks of at least this size in acres")
)
# Date filter
# Opening date filter with better label
opening_date = DateFromToRangeFilter(
field_name='opening_date'
field_name='opening_date',
label=_("Opening Date Range"),
help_text=_("Filter parks by their opening date")
)
def filter_search(self, queryset, name, value):
@@ -94,25 +116,26 @@ class ParkFilter(LocationFilterMixin, RatingFilterMixin, DateRangeFilterMixin, F
def filter_has_owner(self, queryset, name, value):
"""Filter parks based on whether they have an owner"""
return queryset.filter(owner__isnull=not value)
@property
def qs(self):
"""Override qs property to ensure we always use base queryset with annotations"""
if not hasattr(self, '_qs'):
# Start with the base queryset that includes annotations
base_qs = get_base_park_queryset()
if not self.is_bound:
self._qs = base_qs
return self._qs
if not self.form.is_valid():
self._qs = base_qs.none()
return self._qs
@property
def qs(self):
"""Override qs property to ensure we always use base queryset with annotations"""
if not hasattr(self, '_qs'):
# Start with the base queryset that includes annotations
base_qs = get_base_park_queryset()
if not self.is_bound:
self._qs = base_qs
return self._qs
if not self.form.is_valid():
self._qs = base_qs.none()
return self._qs
self._qs = base_qs
for name, value in self.form.cleaned_data.items():
if value in [None, '', 0] and name not in ['has_owner']:
continue
self._qs = self.filters[name].filter(self._qs, value)
self._qs = self._qs.distinct()
return self._qs
self._qs = base_qs
for name, value in self.form.cleaned_data.items():
if value in [None, '', 0] and name not in ['has_owner']:
continue
self._qs = self.filters[name].filter(self._qs, value)
self._qs = self._qs.distinct()
return self._qs