from django.core.management.base import BaseCommand from django.db import transaction, connection import logging from parks.models import Company, Park, ParkArea, ParkReview, ParkLocation from rides.models import ( Company as RideCompany, Ride, RideModel, RideReview, RollerCoasterStats, ) from accounts.models import User class Command(BaseCommand): help = "Seeds comprehensive sample data for the ThrillWiki theme park application" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.logger = logging.getLogger(__name__) def cleanup_existing_data(self): """Clean up all existing sample data before creating new data""" self.stdout.write("Cleaning up existing sample data...") try: with transaction.atomic(): # Count existing data for logging park_review_count = ParkReview.objects.count() ride_review_count = RideReview.objects.count() rollercoaster_stats_count = RollerCoasterStats.objects.count() ride_count = Ride.objects.count() ride_model_count = RideModel.objects.count() park_area_count = ParkArea.objects.count() park_location_count = ParkLocation.objects.count() park_count = Park.objects.count() ride_company_count = RideCompany.objects.count() company_count = Company.objects.count() test_user_count = User.objects.filter(username="testuser").count() # Log what will be deleted self.stdout.write(f" Found {park_review_count} park reviews to delete") self.stdout.write(f" Found {ride_review_count} ride reviews to delete") self.stdout.write( f" Found {rollercoaster_stats_count} roller coaster stats to delete" ) self.stdout.write(f" Found {ride_count} rides to delete") self.stdout.write(f" Found {ride_model_count} ride models to delete") self.stdout.write(f" Found {park_area_count} park areas to delete") self.stdout.write( f" Found {park_location_count} park locations to delete" ) self.stdout.write(f" Found {park_count} parks to delete") self.stdout.write( f" Found {ride_company_count} ride companies to delete" ) self.stdout.write(f" Found {company_count} park companies to delete") self.stdout.write(f" Found {test_user_count} test users to delete") # Delete in order to avoid foreign key constraint violations # Reviews first (they reference other objects) if park_review_count > 0: ParkReview.objects.all().delete() self.stdout.write(f" Deleted {park_review_count} park reviews") if ride_review_count > 0: RideReview.objects.all().delete() self.stdout.write(f" Deleted {ride_review_count} ride reviews") # Roller coaster stats (references Ride) if rollercoaster_stats_count > 0: RollerCoasterStats.objects.all().delete() self.stdout.write( f" Deleted {rollercoaster_stats_count} roller coaster stats" ) # Rides (references Park, RideCompany, RideModel) if ride_count > 0: Ride.objects.all().delete() self.stdout.write(f" Deleted {ride_count} rides") # Ride models (referenced by Ride) if ride_model_count > 0: RideModel.objects.all().delete() self.stdout.write(f" Deleted {ride_model_count} ride models") # Park areas (references Park) if park_area_count > 0: ParkArea.objects.all().delete() self.stdout.write(f" Deleted {park_area_count} park areas") # Park locations (references Park) if park_location_count > 0: ParkLocation.objects.all().delete() self.stdout.write(f" Deleted {park_location_count} park locations") # Parks (referenced by many models) if park_count > 0: Park.objects.all().delete() self.stdout.write(f" Deleted {park_count} parks") # Ride companies (referenced by Ride, RideModel) if ride_company_count > 0: RideCompany.objects.all().delete() self.stdout.write(f" Deleted {ride_company_count} ride companies") # Park companies (referenced by Park) if company_count > 0: Company.objects.all().delete() self.stdout.write(f" Deleted {company_count} park companies") # Only delete test user, not all users if test_user_count > 0: User.objects.filter(username="testuser").delete() self.stdout.write(f" Deleted {test_user_count} test users") self.stdout.write( self.style.SUCCESS("Successfully cleaned up existing sample data!") ) except Exception as e: self.logger.error( f"Error during data cleanup: { str(e)}", exc_info=True, ) self.stdout.write( self.style.ERROR(f"Failed to clean up existing data: {str(e)}") ) raise def handle(self, *args, **options): self.stdout.write("Starting sample data creation...") try: # Check if required tables exist if not self.check_required_tables(): self.stdout.write( self.style.ERROR( "Required database tables are missing. Please run migrations first." ) ) return # Clean up existing data first self.cleanup_existing_data() # Use transaction to ensure data consistency with transaction.atomic(): # Create companies with different roles self.create_companies() # Create parks with proper operator relationships self.create_parks() # Create rides with manufacturer and designer relationships self.create_rides() # Add park areas for variety self.create_park_areas() # Add sample reviews for testing self.create_reviews() self.stdout.write( self.style.SUCCESS("Successfully created comprehensive sample data!") ) except Exception as e: self.logger.error( f"Error during sample data creation: {str(e)}", exc_info=True ) self.stdout.write( self.style.ERROR(f"Failed to create sample data: {str(e)}") ) raise def check_required_tables(self): """Check if all required tables exist in the database""" required_models = [ Company, Park, ParkArea, ParkReview, ParkLocation, RideCompany, Ride, RideModel, RideReview, RollerCoasterStats, User, ] missing_tables = [] for model in required_models: try: # Check if the table exists by trying to get the table name table_name = model._meta.db_table with connection.cursor() as cursor: cursor.execute(f"SELECT 1 FROM {table_name} LIMIT 1") except Exception: missing_tables.append(model._meta.label) if missing_tables: self.stdout.write( self.style.WARNING( f'Missing tables for models: {", ".join(missing_tables)}' ) ) return False self.stdout.write(self.style.SUCCESS("All required tables exist.")) return True def create_companies(self): """Create companies with different roles (operators, manufacturers, designers)""" self.stdout.write("Creating companies...") try: # Park Operators operators_data = [ { "name": "The Walt Disney Company", "roles": ["OPERATOR"], "website": "https://www.disney.com/", "description": "World's largest entertainment company and theme park operator.", "founded_year": 1923, }, { "name": "Universal Parks & Resorts", "roles": ["OPERATOR"], "website": "https://www.universalparks.com/", "description": "Division of Comcast NBCUniversal, operating major theme parks worldwide.", "founded_year": 1964, }, { "name": "Six Flags Entertainment Corporation", "roles": ["OPERATOR"], "website": "https://www.sixflags.com/", "description": "World's largest regional theme park company.", "founded_year": 1961, }, { "name": "Cedar Fair Entertainment Company", "roles": ["OPERATOR"], "website": "https://www.cedarfair.com/", "description": "One of North America's largest operators of regional amusement parks.", "founded_year": 1983, }, { "name": "Herschend Family Entertainment", "roles": ["OPERATOR"], "website": "https://www.hfecorp.com/", "description": "Largest family-owned themed attractions corporation in the United States.", "founded_year": 1950, }, { "name": "Europa-Park GmbH & Co. Mack KG", "roles": ["OPERATOR"], "website": "https://www.europapark.de/", "description": "One of Europe's largest theme parks, located in Germany.", "founded_year": 1975, }, ] # Ride Manufacturers manufacturers_data = [ { "name": "Bolliger & Mabillard", "roles": ["MANUFACTURER"], "website": "https://www.bolliger-mabillard.com/", "description": "Swiss roller coaster manufacturer known for inverted and hyper coasters.", "founded_date": "1988-01-01", }, { "name": "Intamin Amusement Rides", "roles": ["MANUFACTURER"], "website": "https://www.intamin.com/", "description": "Liechtenstein-based manufacturer of roller coasters and thrill rides.", "founded_date": "1967-01-01", }, { "name": "Vekoma Rides Manufacturing", "roles": ["MANUFACTURER"], "website": "https://www.vekoma.com/", "description": "Dutch manufacturer specializing in family and steel roller coasters.", "founded_date": "1926-01-01", }, { "name": "Arrow Dynamics", "roles": ["MANUFACTURER"], "website": "https://www.arrowdynamics.com/", "description": "American manufacturer known for corkscrew and looping coasters.", "founded_date": "1946-01-01", }, { "name": "Rocky Mountain Construction", "roles": ["MANUFACTURER"], "website": "https://www.rockymtnconstruction.com/", "description": "American manufacturer known for I-Box track and wooden coasters.", "founded_date": "2001-01-01", }, { "name": "Mack Rides GmbH & Co KG", "roles": ["MANUFACTURER"], "website": "https://www.mack-rides.com/", "description": "German manufacturer of roller coasters and water rides.", "founded_date": "1780-01-01", }, ] # Ride Designers designers_data = [ { "name": "Werner Stengel", "roles": ["DESIGNER"], "website": "", "description": "German roller coaster designer known for complex layouts and inversions.", }, { "name": "Alan Schilke", "roles": ["DESIGNER"], "website": "", "description": "American roller coaster designer known for family-friendly coasters.", }, { "name": "John Pierce", "roles": ["DESIGNER"], "website": "", "description": "American roller coaster designer and engineer.", }, { "name": "The Gravity Group", "roles": ["DESIGNER"], "website": "https://www.thegravitygroup.com/", "description": "American design firm specializing in roller coaster design.", }, ] # Create companies in parks app (for operators and property owners) self.park_companies = {} for data in operators_data: try: company, created = Company.objects.get_or_create( name=data["name"], defaults={ "roles": data["roles"], "website": data["website"], "description": data["description"], "founded_year": data["founded_year"], }, ) self.park_companies[data["name"]] = company self.stdout.write( f' { "Created" if created else "Found"} park company: { company.name}' ) except Exception as e: self.logger.error( f'Error creating park company {data["name"]}: {str(e)}' ) raise # Create companies in rides app (for manufacturers and designers) self.ride_companies = {} for data in manufacturers_data + designers_data: try: company, created = RideCompany.objects.get_or_create( name=data["name"], defaults={ "roles": data["roles"], "website": data["website"], "description": data["description"], "founded_date": data.get("founded_date"), }, ) self.ride_companies[data["name"]] = company self.stdout.write( f' { "Created" if created else "Found"} ride company: { company.name}' ) except Exception as e: self.logger.error( f'Error creating ride company {data["name"]}: {str(e)}' ) raise except Exception as e: self.logger.error(f"Error in create_companies: {str(e)}") raise def create_parks(self): """Create parks with proper operator relationships""" self.stdout.write("Creating parks...") try: parks_data = [ { "name": "Magic Kingdom", "operator": "The Walt Disney Company", "property_owner": "The Walt Disney Company", "description": "The first theme park at Walt Disney World Resort in Florida, opened in 1971.", "opening_date": "1971-10-01", "size_acres": 142, "website": "https://disneyworld.disney.go.com/destinations/magic-kingdom/", "location": { "street_address": "1180 Seven Seas Dr", "city": "Lake Buena Vista", "state": "Florida", "country": "United States", "postal_code": "32830", "latitude": 28.4177, "longitude": -81.5812, }, }, { "name": "Universal Studios Florida", "operator": "Universal Parks & Resorts", "property_owner": "Universal Parks & Resorts", "description": "Movie and television-based theme park in Orlando, Florida.", "opening_date": "1990-06-07", "size_acres": 108, "website": "https://www.universalorlando.com/web/en/us/theme-parks/universal-studios-florida", "location": { "street_address": "6000 Universal Blvd", "city": "Orlando", "state": "Florida", "country": "United States", "postal_code": "32819", "latitude": 28.4749, "longitude": -81.4687, }, }, { "name": "Cedar Point", "operator": "Cedar Fair Entertainment Company", "property_owner": "Cedar Fair Entertainment Company", "description": 'Known as the "Roller Coaster Capital of the World".', "opening_date": "1870-06-01", "size_acres": 364, "website": "https://www.cedarpoint.com/", "location": { "street_address": "1 Cedar Point Dr", "city": "Sandusky", "state": "Ohio", "country": "United States", "postal_code": "44870", "latitude": 41.4822, "longitude": -82.6835, }, }, { "name": "Europa-Park", "operator": "Europa-Park GmbH & Co. Mack KG", "property_owner": "Europa-Park GmbH & Co. Mack KG", "description": "One of Europe's largest theme parks, located in Germany.", "opening_date": "1975-07-12", "size_acres": 235, "website": "https://www.europapark.de/", "location": { "street_address": "Europa-Park-Straße 2", "city": "Rust", "state": "Baden-Württemberg", "country": "Germany", "postal_code": "77977", "latitude": 48.2667, "longitude": 7.7167, }, }, { "name": "Six Flags Magic Mountain", "operator": "Six Flags Entertainment Corporation", "property_owner": "Six Flags Entertainment Corporation", "description": "Known for its world-record 19 roller coasters.", "opening_date": "1971-05-29", "size_acres": 262, "website": "https://www.sixflags.com/magicmountain", "location": { "street_address": "26101 Magic Mountain Pkwy", "city": "Valencia", "state": "California", "country": "United States", "postal_code": "91355", "latitude": 34.4253, "longitude": -118.5971, }, }, { "name": "Silver Dollar City", "operator": "Herschend Family Entertainment", "property_owner": "Herschend Family Entertainment", "description": "An 1880s-themed park featuring over 40 rides and attractions.", "opening_date": "1960-05-01", "size_acres": 61, "website": "https://www.silverdollarcity.com/", "location": { "street_address": "399 Silver Dollar City Parkway", "city": "Branson", "state": "Missouri", "country": "United States", "postal_code": "65616", "latitude": 36.668497, "longitude": -93.339074, }, }, ] self.parks = {} for park_data in parks_data: try: operator = self.park_companies[park_data["operator"]] property_owner = ( self.park_companies.get(park_data["property_owner"]) if park_data["property_owner"] else None ) park, created = Park.objects.get_or_create( name=park_data["name"], defaults={ "description": park_data["description"], "status": "OPERATING", "opening_date": park_data["opening_date"], "size_acres": park_data["size_acres"], "website": park_data["website"], "operator": operator, "property_owner": property_owner, }, ) self.parks[park_data["name"]] = park self.stdout.write( f' { "Created" if created else "Found"} park: { park.name}' ) # Create location for park if created: try: loc_data = park_data["location"] park_location = ParkLocation.objects.create( park=park, street_address=loc_data["street_address"], city=loc_data["city"], state=loc_data["state"], country=loc_data["country"], postal_code=loc_data["postal_code"], ) # Set coordinates using the helper method park_location.set_coordinates( loc_data["latitude"], loc_data["longitude"] ) park_location.save() except Exception as e: self.logger.error( f'Error creating location for park { park_data["name"]}: { str(e)}' ) raise except Exception as e: self.logger.error( f'Error creating park {park_data["name"]}: {str(e)}' ) raise except Exception as e: self.logger.error(f"Error in create_parks: {str(e)}") raise def create_rides(self): """Create rides with manufacturer and designer relationships""" self.stdout.write("Creating rides...") try: # First create some ride models ride_models_data = [ { "name": "Dive Coaster", "manufacturer": "Bolliger & Mabillard", "category": "RC", "description": "Inverted roller coaster with a vertical drop and non-inverting loop", }, { "name": "Hyper Coaster", "manufacturer": "Bolliger & Mabillard", "category": "RC", "description": "Steel roller coaster with heights over 200 feet", }, { "name": "Boomerang", "manufacturer": "Vekoma Rides Manufacturing", "category": "RC", "description": "Shuttle roller coaster that runs forward and backward", }, { "name": "Corkscrew Coaster", "manufacturer": "Arrow Dynamics", "category": "RC", "description": "Early steel coaster design with corkscrew elements", }, { "name": "I-Box Track", "manufacturer": "Rocky Mountain Construction", "category": "RC", "description": "Smooth-riding steel track system for wooden coasters", }, { "name": "Powered Coaster", "manufacturer": "Mack Rides GmbH & Co KG", "category": "RC", "description": "Family-friendly steel roller coaster", }, ] self.ride_models = {} for model_data in ride_models_data: try: manufacturer = self.ride_companies.get(model_data["manufacturer"]) model, created = RideModel.objects.get_or_create( name=model_data["name"], manufacturer=manufacturer, defaults={ "description": model_data["description"], "category": model_data["category"], }, ) self.ride_models[model_data["name"]] = model self.stdout.write( f' { "Created" if created else "Found"} ride model: { model.name}' ) except Exception as e: self.logger.error( f'Error creating ride model { model_data["name"]}: { str(e)}' ) raise # Create rides rides_data = [ { "name": "Millennium Force", "park": "Cedar Point", "manufacturer": "Bolliger & Mabillard", "designer": "Werner Stengel", "ride_model": "Hyper Coaster", "category": "RC", "description": "World's first hyper coaster reaching speeds of 93 mph.", "opening_date": "2000-05-13", "coaster_stats": { "height_ft": 310, "length_ft": 6595, "speed_mph": 93, "inversions": 0, "ride_time_seconds": 165, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 300, "launch_type": "CHAIN", "trains_count": 3, "cars_per_train": 9, "seats_per_car": 4, }, }, { "name": "Top Thrill Dragster", "park": "Cedar Point", "manufacturer": "Intamin Amusement Rides", "designer": "Werner Stengel", "category": "RC", "description": "World's first strata coaster reaching 420 feet.", "opening_date": "2003-05-04", "coaster_stats": { "height_ft": 420, "length_ft": 2800, "speed_mph": 120, "inversions": 0, "ride_time_seconds": 17, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 400, "launch_type": "HYDRAULIC", "trains_count": 1, "cars_per_train": 1, "seats_per_car": 16, }, }, { "name": "Silver Star", "park": "Europa-Park", "manufacturer": "Bolliger & Mabillard", "designer": "Werner Stengel", "ride_model": "Dive Coaster", "category": "RC", "description": "Europe's first dive coaster with a 300-foot drop.", "opening_date": "2002-03-23", "coaster_stats": { "height_ft": 239, "length_ft": 5249, "speed_mph": 80, "inversions": 0, "ride_time_seconds": 240, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 197, "launch_type": "CHAIN", "trains_count": 2, "cars_per_train": 10, "seats_per_car": 2, }, }, { "name": "Blue Fire", "park": "Europa-Park", "manufacturer": "Mack Rides GmbH & Co KG", "designer": "John Pierce", "ride_model": "Powered Coaster", "category": "RC", "description": "Launched roller coaster with a 124-foot drop.", "opening_date": "2009-04-25", "coaster_stats": { "height_ft": 124, "length_ft": 2789, "speed_mph": 62, "inversions": 0, "ride_time_seconds": 120, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 98, "launch_type": "HYDRAULIC", "trains_count": 2, "cars_per_train": 5, "seats_per_car": 4, }, }, { "name": "Space Mountain", "park": "Magic Kingdom", "manufacturer": "Arrow Dynamics", "designer": "John Pierce", "category": "RC", "description": "Indoor space-themed roller coaster.", "opening_date": "1975-01-15", "coaster_stats": { "height_ft": 183, "length_ft": 3200, "speed_mph": 35, "inversions": 0, "ride_time_seconds": 180, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 150, "launch_type": "CHAIN", "trains_count": 2, "cars_per_train": 6, "seats_per_car": 2, }, }, { "name": "Big Thunder Mountain Railroad", "park": "Magic Kingdom", "manufacturer": "Arrow Dynamics", "designer": "The Gravity Group", "category": "RC", "description": "Mine train roller coaster themed as a runaway mining train.", "opening_date": "1980-11-15", "coaster_stats": { "height_ft": 146, "length_ft": 3280, "speed_mph": 35, "inversions": 0, "ride_time_seconds": 240, "track_material": "STEEL", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 128, "launch_type": "CHAIN", "trains_count": 3, "cars_per_train": 5, "seats_per_car": 4, }, }, { "name": "Maverick", "park": "Cedar Point", "manufacturer": "Intamin Amusement Rides", "designer": "Werner Stengel", "category": "RC", "description": "Wild mouse coaster with a 100-foot drop.", "opening_date": "2007-05-26", "coaster_stats": { "height_ft": 105, "length_ft": 4450, "speed_mph": 70, "inversions": 0, "ride_time_seconds": 180, "track_material": "STEEL", "roller_coaster_type": "WILD_MOUSE", "max_drop_height_ft": 100, "launch_type": "CHAIN", "trains_count": 2, "cars_per_train": 4, "seats_per_car": 4, }, }, { "name": "Time Traveler", "park": "Silver Dollar City", "manufacturer": "Rocky Mountain Construction", "designer": "Alan Schilke", "ride_model": "I-Box Track", "category": "RC", "description": "Wooden coaster with steel I-Box track for smooth riding.", "opening_date": "2018-04-28", "coaster_stats": { "height_ft": 165, "length_ft": 5832, "speed_mph": 72, "inversions": 0, "ride_time_seconds": 240, "track_material": "HYBRID", "roller_coaster_type": "SITDOWN", "max_drop_height_ft": 155, "launch_type": "CHAIN", "trains_count": 2, "cars_per_train": 6, "seats_per_car": 2, }, }, ] self.rides = {} for ride_data in rides_data: try: park = self.parks[ride_data["park"]] manufacturer = self.ride_companies.get( ride_data.get("manufacturer") ) designer = self.ride_companies.get(ride_data.get("designer")) ride_model = self.ride_models.get(ride_data.get("ride_model")) ride, created = Ride.objects.get_or_create( name=ride_data["name"], park=park, defaults={ "description": ride_data["description"], "category": ride_data["category"], "status": "OPERATING", "opening_date": ride_data["opening_date"], "manufacturer": manufacturer, "designer": designer, "ride_model": ride_model, }, ) self.rides[ride_data["name"]] = ride self.stdout.write( f' { "Created" if created else "Found"} ride: { ride.name}' ) # Create roller coaster stats if provided if created and "coaster_stats" in ride_data: try: stats_data = ride_data["coaster_stats"] RollerCoasterStats.objects.create(ride=ride, **stats_data) except Exception as e: self.logger.error( f'Error creating stats for ride { ride_data["name"]}: { str(e)}' ) raise except Exception as e: self.logger.error( f'Error creating ride {ride_data["name"]}: {str(e)}' ) raise except Exception as e: self.logger.error(f"Error in create_rides: {str(e)}") raise def create_park_areas(self): """Add park areas for variety""" self.stdout.write("Creating park areas...") try: areas_data = [ { "park": "Magic Kingdom", "areas": [ { "name": "Main Street, U.S.A.", "description": "Victorian-era themed entrance corridor", }, { "name": "Adventureland", "description": "Exotic tropical places themed area", }, { "name": "Frontierland", "description": "American Old West themed area", }, { "name": "Liberty Square", "description": "Colonial America themed area", }, { "name": "Fantasyland", "description": "Fairy tale themed area", }, { "name": "Tomorrowland", "description": "Future themed area", }, ], }, { "park": "Universal Studios Florida", "areas": [ { "name": "Production Central", "description": "Main entrance area with movie-themed attractions", }, { "name": "New York", "description": "Themed after New York City streets", }, { "name": "San Francisco", "description": "Themed after San Francisco's waterfront", }, { "name": "The Wizarding World of Harry Potter - Diagon Alley", "description": "Themed after the Harry Potter series", }, { "name": "Springfield", "description": "Themed after The Simpsons hometown", }, ], }, { "park": "Cedar Point", "areas": [ { "name": "Frontiertown", "description": "Western-themed area with multiple roller coasters", }, { "name": "Millennium Island", "description": "Home to the Millennium Force roller coaster", }, { "name": "Cedar Point Shores", "description": "Waterpark area", }, { "name": "Top Thrill Dragster", "description": "Area surrounding the iconic launched coaster", }, ], }, { "park": "Europa-Park", "areas": [ { "name": "Germany", "description": "German-themed area", }, { "name": "France", "description": "French-themed area", }, { "name": "England", "description": "English-themed area", }, { "name": "Italy", "description": "Italian-themed area", }, { "name": "Spain", "description": "Spanish-themed area", }, { "name": "Portugal", "description": "Portuguese-themed area", }, ], }, ] for area_group in areas_data: try: park = self.parks[area_group["park"]] for area_data in area_group["areas"]: area, created = ParkArea.objects.get_or_create( name=area_data["name"], park=park, defaults={ "description": area_data["description"], "opening_date": park.opening_date, }, ) self.stdout.write( f' { "Created" if created else "Found"} area: { area.name} in { park.name}' ) except Exception as e: self.logger.error( f'Error creating areas for park { area_group["park"]}: { str(e)}' ) raise except Exception as e: self.logger.error(f"Error in create_park_areas: {str(e)}") raise def create_reviews(self): """Add sample reviews for testing""" self.stdout.write("Creating sample reviews...") try: # Create a test user if none exists test_user, created = User.objects.get_or_create( username="testuser", defaults={ "email": "test@example.com", "first_name": "Test", "last_name": "User", }, ) if created: test_user.set_password("testpass123") test_user.save() # Park reviews park_reviews_data = [ { "park": "Cedar Point", "rating": 10, "title": "Best roller coaster park in the world!", "content": "Cedar Point is absolutely incredible. The Millennium Force is a must-ride. The park is clean, well-maintained, and the staff is friendly. Highly recommend!", "visit_date": "2023-08-15", }, { "park": "Magic Kingdom", "rating": 9, "title": "Magical experience for all ages", "content": "Disney does it again with Magic Kingdom. The attention to detail is amazing and the shows are spectacular. Space Mountain is a classic.", "visit_date": "2023-07-20", }, { "park": "Europa-Park", "rating": 9, "title": "Europe's best theme park", "content": "Europa-Park is fantastic! The theming is incredible and the rides are world-class. Silver Star is absolutely breathtaking.", "visit_date": "2023-06-10", }, { "park": "Universal Studios Florida", "rating": 8, "title": "Great movie-themed attractions", "content": "Universal has some amazing rides, especially in the Harry Potter area. The theming is top-notch and the shows are entertaining.", "visit_date": "2023-05-05", }, ] for review_data in park_reviews_data: try: park = self.parks[review_data["park"]] review, created = ParkReview.objects.get_or_create( park=park, user=test_user, defaults={ "rating": review_data["rating"], "title": review_data["title"], "content": review_data["content"], "visit_date": review_data["visit_date"], "is_published": True, }, ) self.stdout.write( f' { "Created" if created else "Found"} park review: { review.title}' ) except Exception as e: self.logger.error( f'Error creating park review for { review_data["park"]}: { str(e)}' ) raise # Ride reviews ride_reviews_data = [ { "ride": "Millennium Force", "rating": 10, "title": "The king of roller coasters!", "content": "Absolutely incredible ride! The first drop is breathtaking and the speed is unreal. A must-experience for any coaster enthusiast.", "visit_date": "2023-08-15", }, { "ride": "Top Thrill Dragster", "rating": 9, "title": "Incredible launch and height", "content": "The launch is intense and reaching the top of the 420-foot tower is amazing. The view from the top is spectacular!", "visit_date": "2023-08-16", }, { "ride": "Silver Star", "rating": 10, "title": "Best dive coaster in Europe", "content": "The dive drop is incredible! The theming around the ride is beautiful and the overall experience is fantastic.", "visit_date": "2023-06-10", }, { "ride": "Space Mountain", "rating": 8, "title": "Classic Disney coaster", "content": "A classic that never gets old. The indoor setting and space theme make it unique. Great for all ages.", "visit_date": "2023-07-20", }, ] for review_data in ride_reviews_data: try: ride = self.rides[review_data["ride"]] review, created = RideReview.objects.get_or_create( ride=ride, user=test_user, defaults={ "rating": review_data["rating"], "title": review_data["title"], "content": review_data["content"], "visit_date": review_data["visit_date"], "is_published": True, }, ) self.stdout.write( f' { "Created" if created else "Found"} ride review: { review.title}' ) except Exception as e: self.logger.error( f'Error creating ride review for { review_data["ride"]}: { str(e)}' ) raise self.stdout.write(self.style.SUCCESS("Sample data creation completed!")) except Exception as e: self.logger.error(f"Error in create_reviews: {str(e)}") raise