mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 17:11:09 -05:00
remove backend
This commit is contained in:
302
apps/rides/selectors.py
Normal file
302
apps/rides/selectors.py
Normal file
@@ -0,0 +1,302 @@
|
||||
"""
|
||||
Selectors for ride-related data retrieval.
|
||||
Following Django styleguide pattern for separating data access from business logic.
|
||||
"""
|
||||
|
||||
from typing import Optional, Dict, Any
|
||||
from django.db.models import QuerySet, Q, Count, Avg, Prefetch
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.contrib.gis.measure import Distance
|
||||
|
||||
from .models import Ride, RideModel, RideReview
|
||||
from .choices import RIDE_CATEGORIES
|
||||
|
||||
|
||||
def ride_list_for_display(
|
||||
*, filters: Optional[Dict[str, Any]] = None
|
||||
) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get rides optimized for list display with related data.
|
||||
|
||||
Args:
|
||||
filters: Optional dictionary of filter parameters
|
||||
|
||||
Returns:
|
||||
QuerySet of rides with optimized queries
|
||||
"""
|
||||
queryset = (
|
||||
Ride.objects.select_related(
|
||||
"park",
|
||||
"park__operator",
|
||||
"manufacturer",
|
||||
"designer",
|
||||
"ride_model",
|
||||
"park_area",
|
||||
)
|
||||
.prefetch_related("park__location")
|
||||
.annotate(average_rating_calculated=Avg("reviews__rating"))
|
||||
)
|
||||
|
||||
if filters:
|
||||
if "status" in filters and filters["status"]:
|
||||
queryset = queryset.filter(status__in=filters["status"])
|
||||
if "category" in filters and filters["category"]:
|
||||
queryset = queryset.filter(category__in=filters["category"])
|
||||
if "manufacturer" in filters:
|
||||
queryset = queryset.filter(manufacturer=filters["manufacturer"])
|
||||
if "park" in filters:
|
||||
queryset = queryset.filter(park=filters["park"])
|
||||
if "search" in filters:
|
||||
search_term = filters["search"]
|
||||
queryset = queryset.filter(
|
||||
Q(name__icontains=search_term)
|
||||
| Q(description__icontains=search_term)
|
||||
| Q(park__name__icontains=search_term)
|
||||
)
|
||||
|
||||
return queryset.order_by("park__name", "name")
|
||||
|
||||
|
||||
def ride_detail_optimized(*, slug: str, park_slug: str) -> Ride:
|
||||
"""
|
||||
Get a single ride with all related data optimized for detail view.
|
||||
|
||||
Args:
|
||||
slug: Ride slug identifier
|
||||
park_slug: Park slug for the ride
|
||||
|
||||
Returns:
|
||||
Ride instance with optimized prefetches
|
||||
|
||||
Raises:
|
||||
Ride.DoesNotExist: If ride doesn't exist
|
||||
"""
|
||||
return (
|
||||
Ride.objects.select_related(
|
||||
"park",
|
||||
"park__operator",
|
||||
"manufacturer",
|
||||
"designer",
|
||||
"ride_model",
|
||||
"park_area",
|
||||
)
|
||||
.prefetch_related(
|
||||
"park__location",
|
||||
Prefetch(
|
||||
"reviews",
|
||||
queryset=RideReview.objects.select_related("user").filter(
|
||||
is_published=True
|
||||
),
|
||||
),
|
||||
"photos",
|
||||
)
|
||||
.get(slug=slug, park__slug=park_slug)
|
||||
)
|
||||
|
||||
|
||||
def rides_by_category(*, category: str) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get all rides in a specific category.
|
||||
|
||||
Args:
|
||||
category: Ride category code
|
||||
|
||||
Returns:
|
||||
QuerySet of rides in the category
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(category=category)
|
||||
.select_related("park", "manufacturer", "designer")
|
||||
.prefetch_related("park__location")
|
||||
.annotate(average_rating_calculated=Avg("reviews__rating"))
|
||||
.order_by("park__name", "name")
|
||||
)
|
||||
|
||||
|
||||
def rides_by_manufacturer(*, manufacturer_id: int) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get all rides manufactured by a specific company.
|
||||
|
||||
Args:
|
||||
manufacturer_id: Company ID of the manufacturer
|
||||
|
||||
Returns:
|
||||
QuerySet of rides by the manufacturer
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(manufacturer_id=manufacturer_id)
|
||||
.select_related("park", "manufacturer", "ride_model")
|
||||
.prefetch_related("park__location")
|
||||
.annotate(average_rating_calculated=Avg("reviews__rating"))
|
||||
.order_by("park__name", "name")
|
||||
)
|
||||
|
||||
|
||||
def rides_by_designer(*, designer_id: int) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get all rides designed by a specific company.
|
||||
|
||||
Args:
|
||||
designer_id: Company ID of the designer
|
||||
|
||||
Returns:
|
||||
QuerySet of rides by the designer
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(designer_id=designer_id)
|
||||
.select_related("park", "designer", "ride_model")
|
||||
.prefetch_related("park__location")
|
||||
.annotate(average_rating_calculated=Avg("reviews__rating"))
|
||||
.order_by("park__name", "name")
|
||||
)
|
||||
|
||||
|
||||
def rides_in_park(*, park_slug: str) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get all rides in a specific park.
|
||||
|
||||
Args:
|
||||
park_slug: Slug of the park
|
||||
|
||||
Returns:
|
||||
QuerySet of rides in the park
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(park__slug=park_slug)
|
||||
.select_related("manufacturer", "designer", "ride_model", "park_area")
|
||||
.prefetch_related()
|
||||
.annotate(average_rating_calculated=Avg("reviews__rating"))
|
||||
.order_by("park_area__name", "name")
|
||||
)
|
||||
|
||||
|
||||
def rides_near_location(
|
||||
*, point: Point, distance_km: float = 50, limit: int = 10
|
||||
) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get rides near a specific geographic location.
|
||||
|
||||
Args:
|
||||
point: Geographic point (longitude, latitude)
|
||||
distance_km: Maximum distance in kilometers
|
||||
limit: Maximum number of results
|
||||
|
||||
Returns:
|
||||
QuerySet of nearby rides ordered by distance
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(
|
||||
park__location__coordinates__distance_lte=(
|
||||
point,
|
||||
Distance(km=distance_km),
|
||||
)
|
||||
)
|
||||
.select_related("park", "manufacturer")
|
||||
.prefetch_related("park__location")
|
||||
.distance(point)
|
||||
.order_by("distance")[:limit]
|
||||
)
|
||||
|
||||
|
||||
def ride_models_with_installations() -> QuerySet[RideModel]:
|
||||
"""
|
||||
Get ride models that have installations with counts.
|
||||
|
||||
Returns:
|
||||
QuerySet of ride models with installation counts
|
||||
"""
|
||||
return (
|
||||
RideModel.objects.annotate(installation_count=Count("rides"))
|
||||
.filter(installation_count__gt=0)
|
||||
.select_related("manufacturer")
|
||||
.order_by("-installation_count", "name")
|
||||
)
|
||||
|
||||
|
||||
def ride_search_autocomplete(*, query: str, limit: int = 10) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get rides matching a search query for autocomplete functionality.
|
||||
|
||||
Args:
|
||||
query: Search string
|
||||
limit: Maximum number of results
|
||||
|
||||
Returns:
|
||||
QuerySet of matching rides for autocomplete
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(
|
||||
Q(name__icontains=query)
|
||||
| Q(park__name__icontains=query)
|
||||
| Q(manufacturer__name__icontains=query)
|
||||
)
|
||||
.select_related("park", "manufacturer")
|
||||
.prefetch_related("park__location")
|
||||
.order_by("park__name", "name")[:limit]
|
||||
)
|
||||
|
||||
|
||||
def rides_with_recent_reviews(*, days: int = 30) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get rides that have received reviews in the last N days.
|
||||
|
||||
Args:
|
||||
days: Number of days to look back for reviews
|
||||
|
||||
Returns:
|
||||
QuerySet of rides with recent reviews
|
||||
"""
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
|
||||
cutoff_date = timezone.now() - timedelta(days=days)
|
||||
|
||||
return (
|
||||
Ride.objects.filter(
|
||||
reviews__created_at__gte=cutoff_date, reviews__is_published=True
|
||||
)
|
||||
.select_related("park", "manufacturer")
|
||||
.prefetch_related("park__location")
|
||||
.annotate(
|
||||
recent_review_count=Count(
|
||||
"reviews", filter=Q(reviews__created_at__gte=cutoff_date)
|
||||
)
|
||||
)
|
||||
.order_by("-recent_review_count")
|
||||
.distinct()
|
||||
)
|
||||
|
||||
|
||||
def ride_statistics_by_category() -> Dict[str, Any]:
|
||||
"""
|
||||
Get ride statistics grouped by category.
|
||||
|
||||
Returns:
|
||||
Dictionary containing ride statistics by category
|
||||
"""
|
||||
|
||||
stats = {}
|
||||
for category in RIDE_CATEGORIES:
|
||||
if category.value: # Skip empty choice
|
||||
count = Ride.objects.filter(category=category.value).count()
|
||||
stats[category.value] = {"name": category.label, "count": count}
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def rides_by_opening_year(*, year: int) -> QuerySet[Ride]:
|
||||
"""
|
||||
Get rides that opened in a specific year.
|
||||
|
||||
Args:
|
||||
year: The opening year
|
||||
|
||||
Returns:
|
||||
QuerySet of rides that opened in the specified year
|
||||
"""
|
||||
return (
|
||||
Ride.objects.filter(opening_date__year=year)
|
||||
.select_related("park", "manufacturer")
|
||||
.prefetch_related("park__location")
|
||||
.order_by("opening_date", "park__name", "name")
|
||||
)
|
||||
Reference in New Issue
Block a user