Integrate parks app with site-wide search system; add filter configuration, error handling, and search interfaces

This commit is contained in:
pacnpal
2025-02-12 16:59:20 -05:00
parent af57592496
commit 1fe299fb4b
13 changed files with 1267 additions and 72 deletions

View File

@@ -5,6 +5,8 @@ from django.shortcuts import get_object_or_404, render
from django.core.serializers.json import DjangoJSONEncoder
from django.urls import reverse
from django.db.models import Q, Avg, Count, QuerySet, Model
from search.mixins import HTMXFilterableMixin
from .filters import ParkFilter
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
@@ -49,16 +51,26 @@ def get_park_areas(request: HttpRequest) -> HttpResponse:
def search_parks(request: HttpRequest) -> HttpResponse:
"""Search parks and return results for HTMX"""
query = request.GET.get('q', '').strip()
# If no query, show first 10 parks
if not query:
parks = Park.objects.all().order_by('name')[:10]
else:
parks = Park.objects.filter(name__icontains=query).order_by('name')[:10]
return render(request, "parks/partials/park_search_results.html", {"parks": parks})
"""Search parks and return results for quick searches (dropdowns, etc)"""
try:
queryset = (
Park.objects.prefetch_related('location', 'photos')
.order_by('name')
)
filter_params = {'search': request.GET.get('q', '').strip()}
park_filter = ParkFilter(filter_params, queryset=queryset)
parks = park_filter.qs[:10] # Limit to 10 results
return render(request, "parks/partials/park_search_results.html", {
"parks": parks,
"is_quick_search": True
})
except Exception as e:
return render(request, "parks/partials/park_search_results.html", {
"error": f"Error performing search: {str(e)}",
"is_quick_search": True
})
def location_search(request: HttpRequest) -> JsonResponse:
@@ -145,64 +157,44 @@ def add_park_button(request: HttpRequest) -> HttpResponse:
return render(request, "parks/partials/add_park_button.html")
class ParkListView(ListView):
class ParkListView(HTMXFilterableMixin, ListView):
model = Park
template_name = "parks/park_list.html"
context_object_name = "parks"
filter_class = ParkFilter
paginate_by = 20
def get_queryset(self) -> QuerySet[Park]:
queryset = Park.objects.select_related("owner").prefetch_related(
"photos", "location"
)
search = self.request.GET.get("search", "").strip()
country = self.request.GET.get("country", "").strip()
region = self.request.GET.get("region", "").strip()
city = self.request.GET.get("city", "").strip()
statuses = self.request.GET.getlist("status")
if search:
queryset = queryset.filter(
Q(name__icontains=search)
| Q(location__city__icontains=search)
| Q(location__state__icontains=search)
| Q(location__country__icontains=search)
try:
return (
super()
.get_queryset()
.select_related("owner")
.prefetch_related(
"photos",
"location",
"rides",
"rides__manufacturer"
)
.annotate(
total_rides=Count("rides"),
total_coasters=Count("rides", filter=Q(rides__category="RC")),
)
)
if country:
queryset = queryset.filter(location__country__icontains=country)
if region:
queryset = queryset.filter(location__state__icontains=region)
if city:
queryset = queryset.filter(location__city__icontains=city)
if statuses:
queryset = queryset.filter(status__in=statuses)
queryset = queryset.annotate(
total_rides=Count("rides"),
total_coasters=Count("rides", filter=Q(rides__category="RC")),
)
return queryset.distinct()
except Exception as e:
messages.error(self.request, f"Error loading parks: {str(e)}")
return Park.objects.none()
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["current_filters"] = {
"search": self.request.GET.get("search", ""),
"country": self.request.GET.get("country", ""),
"region": self.request.GET.get("region", ""),
"city": self.request.GET.get("city", ""),
"statuses": self.request.GET.getlist("status"),
}
return context
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
if hasattr(request, "htmx") and getattr(request, "htmx", False):
self.template_name = "parks/partials/park_list.html"
return super().get(request, *args, **kwargs)
try:
return super().get_context_data(**kwargs)
except Exception as e:
messages.error(self.request, f"Error applying filters: {str(e)}")
context = {
"filter": self.filterset,
"error": "Unable to apply filters. Please try adjusting your criteria."
}
return context
class ParkDetailView(