refactor: Rename launch_type to propulsion_system across the codebase

This commit is contained in:
pacnpal
2025-09-18 21:01:13 -04:00
parent 516c847377
commit d5cd6ad0a3
21 changed files with 207 additions and 92 deletions

View File

@@ -94,7 +94,7 @@ class RollerCoasterStatsInline(admin.StackedInline):
fields = (
("height_ft", "length_ft", "speed_mph"),
("track_material", "roller_coaster_type"),
("launch_type", "inversions"),
("propulsion_system", "inversions"),
("max_drop_height_ft", "ride_time_seconds"),
("train_style", "trains_count"),
("cars_per_train", "seats_per_car"),
@@ -270,7 +270,7 @@ class RollerCoasterStatsAdmin(admin.ModelAdmin):
list_filter = (
"track_material",
"roller_coaster_type",
"launch_type",
"propulsion_system",
"inversions",
)
search_fields = (
@@ -301,7 +301,7 @@ class RollerCoasterStatsAdmin(admin.ModelAdmin):
"track_material",
"track_type",
"roller_coaster_type",
"launch_type",
"propulsion_system",
"inversions",
)
},

View File

@@ -389,8 +389,8 @@ COASTER_TYPES = [
),
]
# Launch System Choices
LAUNCH_SYSTEMS = [
# Propulsion System Choices
PROPULSION_SYSTEMS = [
RichChoice(
value="CHAIN",
label="Chain Lift",
@@ -442,7 +442,7 @@ LAUNCH_SYSTEMS = [
RichChoice(
value="OTHER",
label="Other",
description="Launch system that doesn't fit standard categories",
description="Propulsion system that doesn't fit standard categories",
metadata={
'color': 'gray',
'icon': 'other',
@@ -760,11 +760,11 @@ def register_rides_choices():
)
register_choices(
name="launch_systems",
choices=LAUNCH_SYSTEMS,
name="propulsion_systems",
choices=PROPULSION_SYSTEMS,
domain="rides",
description="Roller coaster launch and lift systems",
metadata={'domain': 'rides', 'type': 'launch_system', 'applies_to': 'roller_coasters'}
description="Roller coaster propulsion and lift systems",
metadata={'domain': 'rides', 'type': 'propulsion_system', 'applies_to': 'roller_coasters'}
)
register_choices(

View File

@@ -347,12 +347,12 @@ class RollerCoasterForm(BaseFilterForm):
# Get choices - let exceptions propagate if registry fails
track_material_choices = [(choice.value, choice.label) for choice in get_choices("track_materials", "rides")]
coaster_type_choices = [(choice.value, choice.label) for choice in get_choices("coaster_types", "rides")]
launch_type_choices = [(choice.value, choice.label) for choice in get_choices("launch_systems", "rides")]
propulsion_system_choices = [(choice.value, choice.label) for choice in get_choices("propulsion_systems", "rides")]
# Update field choices dynamically
self.fields['track_material'].choices = track_material_choices
self.fields['coaster_type'].choices = coaster_type_choices
self.fields['launch_type'].choices = launch_type_choices
self.fields['propulsion_system'].choices = propulsion_system_choices
height_ft_range = NumberRangeField(
min_val=0, max_val=500, step=1, required=False, label="Height (feet)"
@@ -384,7 +384,7 @@ class RollerCoasterForm(BaseFilterForm):
),
)
launch_type = forms.MultipleChoiceField(
propulsion_system = forms.MultipleChoiceField(
choices=[], # Will be populated in __init__
required=False,
widget=forms.CheckboxSelectMultiple(
@@ -579,7 +579,7 @@ class MasterFilterForm(BaseFilterForm):
"inversions_range",
"track_material",
"coaster_type",
"launch_type",
"propulsion_system",
],
"Company": ["manufacturer_roles", "designer_roles", "founded_date_range"],
}

View File

@@ -271,7 +271,7 @@ class RollerCoasterStatsQuerySet(BaseQuerySet):
def launched_coasters(self):
"""Filter for launched coasters."""
return self.exclude(launch_type="NONE")
return self.exclude(propulsion_system="NONE")
def by_track_type(self, *, track_type: str):
"""Filter by track type."""

View File

@@ -0,0 +1,99 @@
# Generated by Django 5.2.5 on 2025-09-17 01:25
import apps.core.choices.fields
import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("rides", "0023_alter_ridemodelphoto_photo_type_and_more"),
]
operations = [
pgtrigger.migrations.RemoveTrigger(
model_name="rollercoasterstats",
name="insert_insert",
),
pgtrigger.migrations.RemoveTrigger(
model_name="rollercoasterstats",
name="update_update",
),
migrations.RemoveField(
model_name="rollercoasterstats",
name="launch_type",
),
migrations.RemoveField(
model_name="rollercoasterstatsevent",
name="launch_type",
),
migrations.AddField(
model_name="rollercoasterstats",
name="propulsion_system",
field=apps.core.choices.fields.RichChoiceField(
allow_deprecated=False,
choice_group="propulsion_systems",
choices=[
("CHAIN", "Chain Lift"),
("LSM", "LSM Launch"),
("HYDRAULIC", "Hydraulic Launch"),
("GRAVITY", "Gravity"),
("OTHER", "Other"),
],
default="CHAIN",
domain="rides",
help_text="Propulsion or lift system type",
max_length=20,
),
),
migrations.AddField(
model_name="rollercoasterstatsevent",
name="propulsion_system",
field=apps.core.choices.fields.RichChoiceField(
allow_deprecated=False,
choice_group="propulsion_systems",
choices=[
("CHAIN", "Chain Lift"),
("LSM", "LSM Launch"),
("HYDRAULIC", "Hydraulic Launch"),
("GRAVITY", "Gravity"),
("OTHER", "Other"),
],
default="CHAIN",
domain="rides",
help_text="Propulsion or lift system type",
max_length=20,
),
),
pgtrigger.migrations.AddTrigger(
model_name="rollercoasterstats",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "rides_rollercoasterstatsevent" ("cars_per_train", "height_ft", "id", "inversions", "length_ft", "max_drop_height_ft", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "propulsion_system", "ride_id", "ride_time_seconds", "roller_coaster_type", "seats_per_car", "speed_mph", "track_material", "track_type", "train_style", "trains_count") VALUES (NEW."cars_per_train", NEW."height_ft", NEW."id", NEW."inversions", NEW."length_ft", NEW."max_drop_height_ft", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."propulsion_system", NEW."ride_id", NEW."ride_time_seconds", NEW."roller_coaster_type", NEW."seats_per_car", NEW."speed_mph", NEW."track_material", NEW."track_type", NEW."train_style", NEW."trains_count"); RETURN NULL;',
hash="89e2bb56c0befa025a9961f8df34a8a02c09f188",
operation="INSERT",
pgid="pgtrigger_insert_insert_96f8b",
table="rides_rollercoasterstats",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="rollercoasterstats",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "rides_rollercoasterstatsevent" ("cars_per_train", "height_ft", "id", "inversions", "length_ft", "max_drop_height_ft", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "propulsion_system", "ride_id", "ride_time_seconds", "roller_coaster_type", "seats_per_car", "speed_mph", "track_material", "track_type", "train_style", "trains_count") VALUES (NEW."cars_per_train", NEW."height_ft", NEW."id", NEW."inversions", NEW."length_ft", NEW."max_drop_height_ft", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."propulsion_system", NEW."ride_id", NEW."ride_time_seconds", NEW."roller_coaster_type", NEW."seats_per_car", NEW."speed_mph", NEW."track_material", NEW."track_type", NEW."train_style", NEW."trains_count"); RETURN NULL;',
hash="047cc99ae3282202b6dc43c8dbe07690076d5068",
operation="UPDATE",
pgid="pgtrigger_update_update_24e8a",
table="rides_rollercoasterstats",
when="AFTER",
),
),
),
]

View File

@@ -718,10 +718,10 @@ class Ride(TrackedModel):
type_choice = stats.get_roller_coaster_type_rich_choice()
if type_choice:
search_parts.append(type_choice.label)
if stats.launch_type:
launch_choice = stats.get_launch_type_rich_choice()
if launch_choice:
search_parts.append(launch_choice.label)
if stats.propulsion_system:
propulsion_choice = stats.get_propulsion_system_rich_choice()
if propulsion_choice:
search_parts.append(propulsion_choice.label)
if stats.train_style:
search_parts.append(stats.train_style)
except Exception:
@@ -878,12 +878,12 @@ class RollerCoasterStats(models.Model):
max_drop_height_ft = models.DecimalField(
max_digits=6, decimal_places=2, null=True, blank=True
)
launch_type = RichChoiceField(
choice_group="launch_systems",
propulsion_system = RichChoiceField(
choice_group="propulsion_systems",
domain="rides",
max_length=20,
default="CHAIN",
help_text="Launch or lift system type"
help_text="Propulsion or lift system type"
)
train_style = models.CharField(max_length=255, blank=True)
trains_count = models.PositiveIntegerField(null=True, blank=True)

View File

@@ -290,8 +290,8 @@ class SmartRideLoader:
if 'track_material' in filters and filters['track_material']:
q_objects &= Q(coaster_stats__track_material__in=filters['track_material'])
if 'launch_type' in filters and filters['launch_type']:
q_objects &= Q(coaster_stats__launch_type__in=filters['launch_type'])
if 'propulsion_system' in filters and filters['propulsion_system']:
q_objects &= Q(coaster_stats__propulsion_system__in=filters['propulsion_system'])
# Roller coaster height filters
if 'min_height_ft' in filters and filters['min_height_ft']:
@@ -429,7 +429,7 @@ class SmartRideLoader:
'track_material': stats.track_material,
'roller_coaster_type': stats.roller_coaster_type,
'max_drop_height_ft': float(stats.max_drop_height_ft) if stats.max_drop_height_ft else None,
'launch_type': stats.launch_type,
'propulsion_system': stats.propulsion_system,
'train_style': stats.train_style,
'trains_count': stats.trains_count,
'cars_per_train': stats.cars_per_train,
@@ -495,9 +495,9 @@ class SmartRideLoader:
count=models.Count('ride')
).exclude(track_material__isnull=True).order_by('track_material'))
launch_types_data = list(RollerCoasterStats.objects.values('launch_type').annotate(
propulsion_systems_data = list(RollerCoasterStats.objects.values('propulsion_system').annotate(
count=models.Count('ride')
).exclude(launch_type__isnull=True).order_by('launch_type'))
).exclude(propulsion_system__isnull=True).order_by('propulsion_system'))
# Convert to frontend-expected format with value/label/count
categories = [
@@ -536,13 +536,13 @@ class SmartRideLoader:
for item in track_materials_data
]
launch_types = [
propulsion_systems = [
{
'value': item['launch_type'],
'label': self._get_launch_type_label(item['launch_type']),
'value': item['propulsion_system'],
'label': self._get_propulsion_system_label(item['propulsion_system']),
'count': item['count']
}
for item in launch_types_data
for item in propulsion_systems_data
]
# Convert other data to expected format
@@ -633,7 +633,7 @@ class SmartRideLoader:
'statuses': statuses,
'roller_coaster_types': roller_coaster_types,
'track_materials': track_materials,
'launch_types': launch_types,
'propulsion_systems': propulsion_systems,
'parks': parks,
'park_areas': park_areas,
'manufacturers': manufacturers,
@@ -746,6 +746,7 @@ class SmartRideLoader:
'BOBSLED': 'Bobsled',
'PIPELINE': 'Pipeline',
'FOURTH_DIMENSION': '4th Dimension',
'FAMILY': 'Family',
}
if rc_type in rc_type_labels:
return rc_type_labels[rc_type]
@@ -764,9 +765,9 @@ class SmartRideLoader:
else:
raise ValueError(f"Unknown track material: {material}")
def _get_launch_type_label(self, launch_type: str) -> str:
"""Convert launch type to human-readable label."""
launch_labels = {
def _get_propulsion_system_label(self, propulsion_system: str) -> str:
"""Convert propulsion system to human-readable label."""
propulsion_labels = {
'CHAIN': 'Chain Lift',
'LSM': 'Linear Synchronous Motor',
'LIM': 'Linear Induction Motor',
@@ -774,9 +775,10 @@ class SmartRideLoader:
'PNEUMATIC': 'Pneumatic Launch',
'CABLE': 'Cable Lift',
'FLYWHEEL': 'Flywheel Launch',
'NONE': 'No Launch System',
'GRAVITY': 'Gravity',
'NONE': 'No Propulsion System',
}
if launch_type in launch_labels:
return launch_labels[launch_type]
if propulsion_system in propulsion_labels:
return propulsion_labels[propulsion_system]
else:
raise ValueError(f"Unknown launch type: {launch_type}")
raise ValueError(f"Unknown propulsion system: {propulsion_system}")

View File

@@ -60,7 +60,7 @@ class RideSearchService:
"inversions_range",
"track_material",
"coaster_type",
"launch_type",
"propulsion_system",
],
"company": ["manufacturer_roles", "designer_roles", "founded_date_range"],
}
@@ -434,14 +434,14 @@ class RideSearchService:
rollercoasterstats__roller_coaster_type__in=types
)
# Launch type filter (multi-select)
if filters.get("launch_type"):
launch_types = (
filters["launch_type"]
if isinstance(filters["launch_type"], list)
else [filters["launch_type"]]
# Propulsion system filter (multi-select)
if filters.get("propulsion_system"):
propulsion_systems = (
filters["propulsion_system"]
if isinstance(filters["propulsion_system"], list)
else [filters["propulsion_system"]]
)
queryset = queryset.filter(rollercoasterstats__launch_type__in=launch_types)
queryset = queryset.filter(rollercoasterstats__propulsion_system__in=propulsion_systems)
return queryset
@@ -589,7 +589,7 @@ class RideSearchService:
"inversions_range": "Inversions",
"track_material": "Track Material",
"coaster_type": "Coaster Type",
"launch_type": "Launch Type",
"propulsion_system": "Propulsion System",
"manufacturer_roles": "Manufacturer Roles",
"designer_roles": "Designer Roles",
"founded_date_range": "Founded Date",