mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 06:05:18 -05:00
lol
This commit is contained in:
@@ -233,12 +233,16 @@ class HybridParkSerializer(serializers.ModelSerializer):
|
||||
|
||||
# Company fields
|
||||
operator_name = serializers.CharField(source="operator.name", read_only=True)
|
||||
operator_id = serializers.IntegerField(source="operator.id", read_only=True, allow_null=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 property
|
||||
is_closing = serializers.SerializerMethodField()
|
||||
|
||||
# Computed fields for filtering
|
||||
opening_year = serializers.IntegerField(read_only=True)
|
||||
search_text = serializers.CharField(read_only=True)
|
||||
@@ -309,6 +313,11 @@ class HybridParkSerializer(serializers.ModelSerializer):
|
||||
return obj.card_image.image.url
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField())
|
||||
def get_is_closing(self, obj):
|
||||
"""Check if park has an announced closing date in the future."""
|
||||
return obj.is_closing
|
||||
|
||||
class Meta:
|
||||
model = Park
|
||||
fields = [
|
||||
@@ -321,7 +330,10 @@ class HybridParkSerializer(serializers.ModelSerializer):
|
||||
"park_type",
|
||||
# Dates and computed fields
|
||||
"opening_date",
|
||||
"opening_date_precision",
|
||||
"closing_date",
|
||||
"closing_date_precision",
|
||||
"is_closing",
|
||||
"opening_year",
|
||||
"operating_season",
|
||||
# Location fields
|
||||
@@ -333,12 +345,17 @@ class HybridParkSerializer(serializers.ModelSerializer):
|
||||
"longitude",
|
||||
# Company relationships
|
||||
"operator_name",
|
||||
"operator_id",
|
||||
"property_owner_name",
|
||||
# Statistics
|
||||
"size_acres",
|
||||
"average_rating",
|
||||
"ride_count",
|
||||
"coaster_count",
|
||||
# Contact info
|
||||
"phone",
|
||||
"email",
|
||||
"timezone",
|
||||
# Images
|
||||
"banner_image_url",
|
||||
"card_image_url",
|
||||
|
||||
@@ -491,6 +491,374 @@ class HybridRideSerializer(serializers.ModelSerializer):
|
||||
return obj.card_image.image.url
|
||||
return None
|
||||
|
||||
# Computed property
|
||||
is_closing = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.BooleanField())
|
||||
def get_is_closing(self, obj):
|
||||
"""Check if ride has an announced closing date in the future."""
|
||||
return obj.is_closing
|
||||
|
||||
# Water ride stats fields
|
||||
water_wetness_level = serializers.SerializerMethodField()
|
||||
water_splash_height_ft = serializers.SerializerMethodField()
|
||||
water_has_splash_zone = serializers.SerializerMethodField()
|
||||
water_boat_capacity = serializers.SerializerMethodField()
|
||||
water_uses_flume = serializers.SerializerMethodField()
|
||||
water_rapids_sections = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_water_wetness_level(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return obj.water_stats.wetness_level
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_water_splash_height_ft(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return float(obj.water_stats.splash_height_ft) if obj.water_stats.splash_height_ft else None
|
||||
return None
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_water_has_splash_zone(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return obj.water_stats.has_splash_zone
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_water_boat_capacity(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return obj.water_stats.boat_capacity
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_water_uses_flume(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return obj.water_stats.uses_flume
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_water_rapids_sections(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "water_stats") and obj.water_stats:
|
||||
return obj.water_stats.rapids_sections
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
# Dark ride stats fields
|
||||
dark_scene_count = serializers.SerializerMethodField()
|
||||
dark_animatronic_count = serializers.SerializerMethodField()
|
||||
dark_has_projection_technology = serializers.SerializerMethodField()
|
||||
dark_is_interactive = serializers.SerializerMethodField()
|
||||
dark_ride_system = serializers.SerializerMethodField()
|
||||
dark_uses_practical_effects = serializers.SerializerMethodField()
|
||||
dark_uses_motion_base = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_dark_scene_count(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.scene_count
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_dark_animatronic_count(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.animatronic_count
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_dark_has_projection_technology(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.has_projection_technology
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_dark_is_interactive(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.is_interactive
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_dark_ride_system(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.ride_system
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_dark_uses_practical_effects(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.uses_practical_effects
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_dark_uses_motion_base(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "dark_stats") and obj.dark_stats:
|
||||
return obj.dark_stats.uses_motion_base
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
# Flat ride stats fields
|
||||
flat_max_height_ft = serializers.SerializerMethodField()
|
||||
flat_rotation_speed_rpm = serializers.SerializerMethodField()
|
||||
flat_swing_angle_degrees = serializers.SerializerMethodField()
|
||||
flat_motion_type = serializers.SerializerMethodField()
|
||||
flat_arm_count = serializers.SerializerMethodField()
|
||||
flat_seats_per_gondola = serializers.SerializerMethodField()
|
||||
flat_max_g_force = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_flat_max_height_ft(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return float(obj.flat_stats.max_height_ft) if obj.flat_stats.max_height_ft else None
|
||||
return None
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_flat_rotation_speed_rpm(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return float(obj.flat_stats.rotation_speed_rpm) if obj.flat_stats.rotation_speed_rpm else None
|
||||
return None
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_flat_swing_angle_degrees(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return obj.flat_stats.swing_angle_degrees
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_flat_motion_type(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return obj.flat_stats.motion_type
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_flat_arm_count(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return obj.flat_stats.arm_count
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_flat_seats_per_gondola(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return obj.flat_stats.seats_per_gondola
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_flat_max_g_force(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "flat_stats") and obj.flat_stats:
|
||||
return float(obj.flat_stats.max_g_force) if obj.flat_stats.max_g_force else None
|
||||
return None
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
|
||||
# Kiddie ride stats fields
|
||||
kiddie_min_age = serializers.SerializerMethodField()
|
||||
kiddie_max_age = serializers.SerializerMethodField()
|
||||
kiddie_educational_theme = serializers.SerializerMethodField()
|
||||
kiddie_character_theme = serializers.SerializerMethodField()
|
||||
kiddie_guardian_required = serializers.SerializerMethodField()
|
||||
kiddie_adult_ride_along = serializers.SerializerMethodField()
|
||||
kiddie_seats_per_vehicle = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_kiddie_min_age(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.min_age
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_kiddie_max_age(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.max_age
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_kiddie_educational_theme(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.educational_theme or None
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_kiddie_character_theme(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.character_theme or None
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_kiddie_guardian_required(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.guardian_required
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_kiddie_adult_ride_along(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.adult_ride_along
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_kiddie_seats_per_vehicle(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
|
||||
return obj.kiddie_stats.seats_per_vehicle
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
# Transportation stats fields
|
||||
transport_type = serializers.SerializerMethodField()
|
||||
transport_route_length_ft = serializers.SerializerMethodField()
|
||||
transport_stations_count = serializers.SerializerMethodField()
|
||||
transport_vehicle_capacity = serializers.SerializerMethodField()
|
||||
transport_vehicles_count = serializers.SerializerMethodField()
|
||||
transport_round_trip_duration_minutes = serializers.SerializerMethodField()
|
||||
transport_scenic_highlights = serializers.SerializerMethodField()
|
||||
transport_is_one_way = serializers.SerializerMethodField()
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_transport_type(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.transport_type
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.FloatField(allow_null=True))
|
||||
def get_transport_route_length_ft(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return float(obj.transport_stats.route_length_ft) if obj.transport_stats.route_length_ft else None
|
||||
return None
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_transport_stations_count(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.stations_count
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_transport_vehicle_capacity(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.vehicle_capacity
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_transport_vehicles_count(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.vehicles_count
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.IntegerField(allow_null=True))
|
||||
def get_transport_round_trip_duration_minutes(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.round_trip_duration_minutes
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_transport_scenic_highlights(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.scenic_highlights or None
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.BooleanField(allow_null=True))
|
||||
def get_transport_is_one_way(self, obj):
|
||||
try:
|
||||
if hasattr(obj, "transport_stats") and obj.transport_stats:
|
||||
return obj.transport_stats.is_one_way
|
||||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
class Meta:
|
||||
model = Ride
|
||||
fields = [
|
||||
@@ -504,7 +872,10 @@ class HybridRideSerializer(serializers.ModelSerializer):
|
||||
"post_closing_status",
|
||||
# Dates and computed fields
|
||||
"opening_date",
|
||||
"opening_date_precision",
|
||||
"closing_date",
|
||||
"closing_date_precision",
|
||||
"is_closing",
|
||||
"status_since",
|
||||
"opening_year",
|
||||
# Park fields
|
||||
@@ -533,6 +904,9 @@ class HybridRideSerializer(serializers.ModelSerializer):
|
||||
"capacity_per_hour",
|
||||
"ride_duration_seconds",
|
||||
"average_rating",
|
||||
# Additional classification
|
||||
"ride_sub_type",
|
||||
"age_requirement",
|
||||
# Roller coaster stats
|
||||
"coaster_height_ft",
|
||||
"coaster_length_ft",
|
||||
@@ -548,6 +922,46 @@ class HybridRideSerializer(serializers.ModelSerializer):
|
||||
"coaster_trains_count",
|
||||
"coaster_cars_per_train",
|
||||
"coaster_seats_per_car",
|
||||
# Water ride stats
|
||||
"water_wetness_level",
|
||||
"water_splash_height_ft",
|
||||
"water_has_splash_zone",
|
||||
"water_boat_capacity",
|
||||
"water_uses_flume",
|
||||
"water_rapids_sections",
|
||||
# Dark ride stats
|
||||
"dark_scene_count",
|
||||
"dark_animatronic_count",
|
||||
"dark_has_projection_technology",
|
||||
"dark_is_interactive",
|
||||
"dark_ride_system",
|
||||
"dark_uses_practical_effects",
|
||||
"dark_uses_motion_base",
|
||||
# Flat ride stats
|
||||
"flat_max_height_ft",
|
||||
"flat_rotation_speed_rpm",
|
||||
"flat_swing_angle_degrees",
|
||||
"flat_motion_type",
|
||||
"flat_arm_count",
|
||||
"flat_seats_per_gondola",
|
||||
"flat_max_g_force",
|
||||
# Kiddie ride stats
|
||||
"kiddie_min_age",
|
||||
"kiddie_max_age",
|
||||
"kiddie_educational_theme",
|
||||
"kiddie_character_theme",
|
||||
"kiddie_guardian_required",
|
||||
"kiddie_adult_ride_along",
|
||||
"kiddie_seats_per_vehicle",
|
||||
# Transportation stats
|
||||
"transport_type",
|
||||
"transport_route_length_ft",
|
||||
"transport_stations_count",
|
||||
"transport_vehicle_capacity",
|
||||
"transport_vehicles_count",
|
||||
"transport_round_trip_duration_minutes",
|
||||
"transport_scenic_highlights",
|
||||
"transport_is_one_way",
|
||||
# Images
|
||||
"banner_image_url",
|
||||
"card_image_url",
|
||||
|
||||
@@ -32,9 +32,18 @@ from .shared import ModelChoices
|
||||
"roles": ["OPERATOR", "PROPERTY_OWNER"],
|
||||
"description": "Theme park operator based in Ohio",
|
||||
"website": "https://cedarfair.com",
|
||||
"founded_date": "1983-01-01",
|
||||
"person_type": "CORPORATION",
|
||||
"status": "ACTIVE",
|
||||
"founded_year": 1983,
|
||||
"founded_date": "1983-05-01",
|
||||
"founded_date_precision": "MONTH",
|
||||
"logo_url": "https://example.com/logo.png",
|
||||
"banner_image_url": "https://example.com/banner.jpg",
|
||||
"card_image_url": "https://example.com/card.jpg",
|
||||
"average_rating": 4.5,
|
||||
"review_count": 150,
|
||||
"parks_count": 11,
|
||||
"rides_count": 0,
|
||||
"coasters_count": 0,
|
||||
},
|
||||
)
|
||||
]
|
||||
@@ -42,15 +51,35 @@ from .shared import ModelChoices
|
||||
class CompanyDetailOutputSerializer(serializers.Serializer):
|
||||
"""Output serializer for company details."""
|
||||
|
||||
# Core fields
|
||||
id = serializers.IntegerField()
|
||||
name = serializers.CharField()
|
||||
slug = serializers.CharField()
|
||||
roles = serializers.ListField(child=serializers.CharField())
|
||||
description = serializers.CharField()
|
||||
website = serializers.URLField()
|
||||
website = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
# Entity type and status (ported from legacy)
|
||||
person_type = serializers.CharField(required=False, allow_blank=True)
|
||||
status = serializers.CharField()
|
||||
|
||||
# Founding information
|
||||
founded_year = serializers.IntegerField(allow_null=True)
|
||||
founded_date = serializers.DateField(allow_null=True)
|
||||
founded_date_precision = serializers.CharField(required=False, allow_blank=True)
|
||||
|
||||
# Image URLs
|
||||
logo_url = serializers.URLField(required=False, allow_blank=True)
|
||||
banner_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
card_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
# Rating and review aggregates
|
||||
average_rating = serializers.DecimalField(max_digits=3, decimal_places=2, allow_null=True)
|
||||
review_count = serializers.IntegerField()
|
||||
|
||||
# Counts
|
||||
parks_count = serializers.IntegerField()
|
||||
rides_count = serializers.IntegerField()
|
||||
coasters_count = serializers.IntegerField()
|
||||
|
||||
# Metadata
|
||||
created_at = serializers.DateTimeField()
|
||||
@@ -67,7 +96,31 @@ class CompanyCreateInputSerializer(serializers.Serializer):
|
||||
)
|
||||
description = serializers.CharField(allow_blank=True, default="")
|
||||
website = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
# Entity type and status
|
||||
person_type = serializers.ChoiceField(
|
||||
choices=["INDIVIDUAL", "FIRM", "ORGANIZATION", "CORPORATION", "PARTNERSHIP", "GOVERNMENT"],
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
status = serializers.ChoiceField(
|
||||
choices=["ACTIVE", "DEFUNCT", "MERGED", "ACQUIRED", "RENAMED", "DORMANT"],
|
||||
default="ACTIVE",
|
||||
)
|
||||
|
||||
# Founding information
|
||||
founded_year = serializers.IntegerField(required=False, allow_null=True)
|
||||
founded_date = serializers.DateField(required=False, allow_null=True)
|
||||
founded_date_precision = serializers.ChoiceField(
|
||||
choices=["YEAR", "MONTH", "DAY"],
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
|
||||
# Image URLs
|
||||
logo_url = serializers.URLField(required=False, allow_blank=True)
|
||||
banner_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
card_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
|
||||
class CompanyUpdateInputSerializer(serializers.Serializer):
|
||||
@@ -80,7 +133,31 @@ class CompanyUpdateInputSerializer(serializers.Serializer):
|
||||
)
|
||||
description = serializers.CharField(allow_blank=True, required=False)
|
||||
website = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
# Entity type and status
|
||||
person_type = serializers.ChoiceField(
|
||||
choices=["INDIVIDUAL", "FIRM", "ORGANIZATION", "CORPORATION", "PARTNERSHIP", "GOVERNMENT"],
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
status = serializers.ChoiceField(
|
||||
choices=["ACTIVE", "DEFUNCT", "MERGED", "ACQUIRED", "RENAMED", "DORMANT"],
|
||||
required=False,
|
||||
)
|
||||
|
||||
# Founding information
|
||||
founded_year = serializers.IntegerField(required=False, allow_null=True)
|
||||
founded_date = serializers.DateField(required=False, allow_null=True)
|
||||
founded_date_precision = serializers.ChoiceField(
|
||||
choices=["YEAR", "MONTH", "DAY"],
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
|
||||
# Image URLs
|
||||
logo_url = serializers.URLField(required=False, allow_blank=True)
|
||||
banner_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
card_image_url = serializers.URLField(required=False, allow_blank=True)
|
||||
|
||||
|
||||
# === RIDE MODEL SERIALIZERS ===
|
||||
|
||||
@@ -208,6 +208,9 @@ class RideDetailOutputSerializer(serializers.Serializer):
|
||||
banner_image = serializers.SerializerMethodField()
|
||||
card_image = serializers.SerializerMethodField()
|
||||
|
||||
# Former names (name history)
|
||||
former_names = serializers.SerializerMethodField()
|
||||
|
||||
# URL
|
||||
url = serializers.SerializerMethodField()
|
||||
|
||||
@@ -406,6 +409,24 @@ class RideDetailOutputSerializer(serializers.Serializer):
|
||||
|
||||
return None
|
||||
|
||||
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
|
||||
def get_former_names(self, obj):
|
||||
"""Get the former names (name history) for this ride."""
|
||||
from apps.rides.models import RideNameHistory
|
||||
|
||||
former_names = RideNameHistory.objects.filter(ride=obj).order_by("-to_year", "-from_year")
|
||||
|
||||
return [
|
||||
{
|
||||
"id": entry.id,
|
||||
"former_name": entry.former_name,
|
||||
"from_year": entry.from_year,
|
||||
"to_year": entry.to_year,
|
||||
"reason": entry.reason,
|
||||
}
|
||||
for entry in former_names
|
||||
]
|
||||
|
||||
|
||||
class RideImageSettingsInputSerializer(serializers.Serializer):
|
||||
"""Input serializer for setting ride banner and card images."""
|
||||
@@ -841,3 +862,37 @@ class RideReviewUpdateInputSerializer(serializers.Serializer):
|
||||
if value and value > timezone.now().date():
|
||||
raise serializers.ValidationError("Visit date cannot be in the future")
|
||||
return value
|
||||
|
||||
|
||||
# === RIDE NAME HISTORY SERIALIZERS ===
|
||||
|
||||
|
||||
class RideNameHistoryOutputSerializer(serializers.Serializer):
|
||||
"""Output serializer for ride name history (former names)."""
|
||||
|
||||
id = serializers.IntegerField()
|
||||
former_name = serializers.CharField()
|
||||
from_year = serializers.IntegerField(allow_null=True)
|
||||
to_year = serializers.IntegerField(allow_null=True)
|
||||
reason = serializers.CharField()
|
||||
created_at = serializers.DateTimeField()
|
||||
|
||||
|
||||
class RideNameHistoryCreateInputSerializer(serializers.Serializer):
|
||||
"""Input serializer for creating ride name history entries."""
|
||||
|
||||
former_name = serializers.CharField(max_length=200)
|
||||
from_year = serializers.IntegerField(required=False, allow_null=True, min_value=1800, max_value=2100)
|
||||
to_year = serializers.IntegerField(required=False, allow_null=True, min_value=1800, max_value=2100)
|
||||
reason = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")
|
||||
|
||||
def validate(self, attrs):
|
||||
"""Validate year range."""
|
||||
from_year = attrs.get("from_year")
|
||||
to_year = attrs.get("to_year")
|
||||
|
||||
if from_year and to_year and from_year > to_year:
|
||||
raise serializers.ValidationError("From year cannot be after to year")
|
||||
|
||||
return attrs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user