mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 14:31:08 -05:00
Implement hybrid filtering strategy for parks and rides
- Added comprehensive documentation for hybrid filtering implementation, including architecture, API endpoints, performance characteristics, and usage examples. - Developed a hybrid pagination and client-side filtering recommendation, detailing server-side responsibilities and client-side logic. - Created a test script for hybrid filtering endpoints, covering various test cases including basic filtering, search functionality, pagination, and edge cases.
This commit is contained in:
@@ -230,6 +230,151 @@ class ParkPhotoSerializer(serializers.ModelSerializer):
|
||||
)
|
||||
|
||||
|
||||
class HybridParkSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Enhanced serializer for hybrid filtering strategy.
|
||||
Includes all filterable fields for client-side filtering.
|
||||
"""
|
||||
|
||||
# Location fields from related ParkLocation
|
||||
city = serializers.SerializerMethodField()
|
||||
state = serializers.SerializerMethodField()
|
||||
country = serializers.SerializerMethodField()
|
||||
continent = serializers.SerializerMethodField()
|
||||
latitude = serializers.SerializerMethodField()
|
||||
longitude = serializers.SerializerMethodField()
|
||||
|
||||
# Company fields
|
||||
operator_name = serializers.CharField(source="operator.name", read_only=True)
|
||||
property_owner_name = serializers.CharField(source="property_owner.name", read_only=True, allow_null=True)
|
||||
|
||||
# Image URLs for display
|
||||
banner_image_url = serializers.SerializerMethodField()
|
||||
card_image_url = serializers.SerializerMethodField()
|
||||
|
||||
# Computed fields for filtering
|
||||
opening_year = serializers.IntegerField(read_only=True)
|
||||
search_text = serializers.CharField(read_only=True)
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_city(self, obj):
|
||||
"""Get city from related location."""
|
||||
try:
|
||||
return obj.location.city if hasattr(obj, 'location') and obj.location else None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_state(self, obj):
|
||||
"""Get state from related location."""
|
||||
try:
|
||||
return obj.location.state if hasattr(obj, 'location') and obj.location else None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_country(self, obj):
|
||||
"""Get country from related location."""
|
||||
try:
|
||||
return obj.location.country if hasattr(obj, 'location') and obj.location else None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_continent(self, obj):
|
||||
"""Get continent from related location."""
|
||||
try:
|
||||
return obj.location.continent if hasattr(obj, 'location') and obj.location else None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_latitude(self, obj):
|
||||
"""Get latitude from related location."""
|
||||
try:
|
||||
if hasattr(obj, 'location') and obj.location and obj.location.coordinates:
|
||||
return obj.location.coordinates[1] # PostGIS returns [lon, lat]
|
||||
return None
|
||||
except (AttributeError, IndexError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_longitude(self, obj):
|
||||
"""Get longitude from related location."""
|
||||
try:
|
||||
if hasattr(obj, 'location') and obj.location and obj.location.coordinates:
|
||||
return obj.location.coordinates[0] # PostGIS returns [lon, lat]
|
||||
return None
|
||||
except (AttributeError, IndexError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.URLField(allow_null=True))
|
||||
def get_banner_image_url(self, obj):
|
||||
"""Get banner image URL."""
|
||||
if obj.banner_image and obj.banner_image.image:
|
||||
return obj.banner_image.image.url
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.URLField(allow_null=True))
|
||||
def get_card_image_url(self, obj):
|
||||
"""Get card image URL."""
|
||||
if obj.card_image and obj.card_image.image:
|
||||
return obj.card_image.image.url
|
||||
return None
|
||||
|
||||
class Meta:
|
||||
model = Park
|
||||
fields = [
|
||||
# Basic park info
|
||||
"id",
|
||||
"name",
|
||||
"slug",
|
||||
"description",
|
||||
"status",
|
||||
"park_type",
|
||||
|
||||
# Dates and computed fields
|
||||
"opening_date",
|
||||
"closing_date",
|
||||
"opening_year",
|
||||
"operating_season",
|
||||
|
||||
# Location fields
|
||||
"city",
|
||||
"state",
|
||||
"country",
|
||||
"continent",
|
||||
"latitude",
|
||||
"longitude",
|
||||
|
||||
# Company relationships
|
||||
"operator_name",
|
||||
"property_owner_name",
|
||||
|
||||
# Statistics
|
||||
"size_acres",
|
||||
"average_rating",
|
||||
"ride_count",
|
||||
"coaster_count",
|
||||
|
||||
# Images
|
||||
"banner_image_url",
|
||||
"card_image_url",
|
||||
|
||||
# URLs
|
||||
"website",
|
||||
"url",
|
||||
|
||||
# Computed fields for filtering
|
||||
"search_text",
|
||||
|
||||
# Metadata
|
||||
"created_at",
|
||||
"updated_at",
|
||||
]
|
||||
read_only_fields = fields
|
||||
|
||||
|
||||
class ParkSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for the Park model."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user