mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 19:11:08 -05:00
major changes, including tailwind v4
This commit is contained in:
@@ -1,306 +0,0 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.files.temp import NamedTemporaryFile
|
||||
from django.core.files import File
|
||||
import requests
|
||||
from parks.models import Park
|
||||
from rides.models import Ride, RollerCoasterStats
|
||||
from operators.models import Operator
|
||||
from manufacturers.models import Manufacturer
|
||||
from reviews.models import Review
|
||||
from media.models import Photo
|
||||
from django.contrib.auth.models import Permission
|
||||
from datetime import datetime, timedelta
|
||||
import secrets
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
# Park coordinates mapping
|
||||
PARK_COORDINATES = {
|
||||
"Walt Disney World Magic Kingdom": {
|
||||
"latitude": "28.418778",
|
||||
"longitude": "-81.581212",
|
||||
"street_address": "1180 Seven Seas Dr",
|
||||
"city": "Orlando",
|
||||
"state": "Florida",
|
||||
"postal_code": "32836"
|
||||
},
|
||||
"Cedar Point": {
|
||||
"latitude": "41.482207",
|
||||
"longitude": "-82.683523",
|
||||
"street_address": "1 Cedar Point Dr",
|
||||
"city": "Sandusky",
|
||||
"state": "Ohio",
|
||||
"postal_code": "44870"
|
||||
},
|
||||
"Universal's Islands of Adventure": {
|
||||
"latitude": "28.470891",
|
||||
"longitude": "-81.471756",
|
||||
"street_address": "6000 Universal Blvd",
|
||||
"city": "Orlando",
|
||||
"state": "Florida",
|
||||
"postal_code": "32819"
|
||||
},
|
||||
"Alton Towers": {
|
||||
"latitude": "52.988889",
|
||||
"longitude": "-1.892778",
|
||||
"street_address": "Farley Ln",
|
||||
"city": "Alton",
|
||||
"state": "Staffordshire",
|
||||
"postal_code": "ST10 4DB"
|
||||
},
|
||||
"Europa-Park": {
|
||||
"latitude": "48.266031",
|
||||
"longitude": "7.722044",
|
||||
"street_address": "Europa-Park-Straße 2",
|
||||
"city": "Rust",
|
||||
"state": "Baden-Württemberg",
|
||||
"postal_code": "77977"
|
||||
}
|
||||
}
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Seeds the database with initial data"
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
self.stdout.write("Starting database seed...")
|
||||
|
||||
# Clean up media directory
|
||||
self.stdout.write("Cleaning up media directory...")
|
||||
media_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'media')
|
||||
if os.path.exists(media_dir):
|
||||
for item in os.listdir(media_dir):
|
||||
if item != '__init__.py': # Preserve __init__.py
|
||||
item_path = os.path.join(media_dir, item)
|
||||
if os.path.isdir(item_path):
|
||||
shutil.rmtree(item_path)
|
||||
else:
|
||||
os.remove(item_path)
|
||||
|
||||
# Delete all existing data
|
||||
self.stdout.write("Deleting existing data...")
|
||||
User.objects.exclude(username='admin').delete() # Delete all users except admin
|
||||
Park.objects.all().delete()
|
||||
Ride.objects.all().delete()
|
||||
Operator.objects.all().delete()
|
||||
Manufacturer.objects.all().delete()
|
||||
Review.objects.all().delete()
|
||||
Photo.objects.all().delete()
|
||||
|
||||
# Create users and set permissions
|
||||
self.create_users()
|
||||
self.setup_permissions()
|
||||
|
||||
# Create parks and rides
|
||||
self.stdout.write("Creating parks and rides from seed data...")
|
||||
self.create_companies()
|
||||
self.create_manufacturers()
|
||||
self.create_parks_and_rides()
|
||||
|
||||
# Create reviews
|
||||
self.stdout.write("Creating reviews...")
|
||||
self.create_reviews()
|
||||
|
||||
self.stdout.write("Successfully seeded database")
|
||||
|
||||
def setup_permissions(self):
|
||||
"""Set up photo permissions for all users"""
|
||||
self.stdout.write("Setting up photo permissions...")
|
||||
|
||||
# Get photo permissions
|
||||
photo_content_type = ContentType.objects.get_for_model(Photo)
|
||||
photo_permissions = Permission.objects.filter(content_type=photo_content_type)
|
||||
|
||||
# Update all users
|
||||
users = User.objects.all()
|
||||
for user in users:
|
||||
for perm in photo_permissions:
|
||||
user.user_permissions.add(perm)
|
||||
user.save()
|
||||
self.stdout.write(f"Updated permissions for user: {user.username}")
|
||||
|
||||
def create_users(self):
|
||||
self.stdout.write("Creating users...")
|
||||
|
||||
# Try to get admin user
|
||||
try:
|
||||
admin = User.objects.get(username="admin")
|
||||
self.stdout.write("Admin user exists, updating permissions...")
|
||||
except User.DoesNotExist:
|
||||
admin = User.objects.create_superuser("admin", "admin@example.com", "admin")
|
||||
self.stdout.write("Created admin user")
|
||||
|
||||
# Create 10 regular users
|
||||
usernames = [
|
||||
"thrillseeker1",
|
||||
"coasterrider2",
|
||||
"parkfan3",
|
||||
"adventurer4",
|
||||
"funseeker5",
|
||||
"parkexplorer6",
|
||||
"ridetester7",
|
||||
"themepark8",
|
||||
"coaster9",
|
||||
"parkvisitor10"
|
||||
]
|
||||
|
||||
for username in usernames:
|
||||
User.objects.create_user(
|
||||
username=username,
|
||||
email=f"{username}@example.com",
|
||||
[PASSWORD-REMOVED]",
|
||||
)
|
||||
self.stdout.write(f"Created user: {username}")
|
||||
|
||||
def create_companies(self):
|
||||
self.stdout.write("Creating companies...")
|
||||
|
||||
companies = [
|
||||
"The Walt Disney Company",
|
||||
"Cedar Fair",
|
||||
"NBCUniversal",
|
||||
"Merlin Entertainments",
|
||||
"Mack Rides",
|
||||
]
|
||||
|
||||
for name in companies:
|
||||
Operator.objects.create(name=name)
|
||||
self.stdout.write(f"Created company: {name}")
|
||||
|
||||
def create_manufacturers(self):
|
||||
self.stdout.write("Creating manufacturers...")
|
||||
|
||||
manufacturers = [
|
||||
"Walt Disney Imagineering",
|
||||
"Bolliger & Mabillard",
|
||||
"Intamin",
|
||||
"Rocky Mountain Construction",
|
||||
"Vekoma",
|
||||
"Mack Rides",
|
||||
"Oceaneering International",
|
||||
]
|
||||
|
||||
for name in manufacturers:
|
||||
Manufacturer.objects.create(name=name)
|
||||
self.stdout.write(f"Created manufacturer: {name}")
|
||||
|
||||
def download_image(self, url):
|
||||
"""Download image from URL and return as Django File object"""
|
||||
response = requests.get(url, timeout=60)
|
||||
if response.status_code == 200:
|
||||
img_temp = NamedTemporaryFile(delete=True)
|
||||
img_temp.write(response.content)
|
||||
img_temp.flush()
|
||||
return File(img_temp)
|
||||
return None
|
||||
|
||||
def create_parks_and_rides(self):
|
||||
# Load seed data
|
||||
with open(os.path.join(os.path.dirname(__file__), "seed_data.json")) as f:
|
||||
data = json.load(f)
|
||||
|
||||
for park_data in data["parks"]:
|
||||
try:
|
||||
# Create park with location data
|
||||
park_coords = PARK_COORDINATES[park_data["name"]]
|
||||
park = Park.objects.create(
|
||||
name=park_data["name"],
|
||||
country=park_data["country"],
|
||||
opening_date=park_data["opening_date"],
|
||||
status=park_data["status"],
|
||||
description=park_data["description"],
|
||||
website=park_data["website"],
|
||||
operator=Operator.objects.get(name=park_data["owner"]),
|
||||
size_acres=park_data["size_acres"],
|
||||
# Add location fields
|
||||
latitude=park_coords["latitude"],
|
||||
longitude=park_coords["longitude"],
|
||||
street_address=park_coords["street_address"],
|
||||
city=park_coords["city"],
|
||||
state=park_coords["state"],
|
||||
postal_code=park_coords["postal_code"]
|
||||
)
|
||||
|
||||
# Add park photos
|
||||
for photo_url in park_data["photos"]:
|
||||
img_file = self.download_image(photo_url)
|
||||
if img_file:
|
||||
Photo.objects.create(
|
||||
image=img_file,
|
||||
content_type=ContentType.objects.get_for_model(park),
|
||||
object_id=park.id,
|
||||
is_primary=True, # First photo is primary
|
||||
)
|
||||
|
||||
# Create rides
|
||||
for ride_data in park_data["rides"]:
|
||||
ride = Ride.objects.create(
|
||||
name=ride_data["name"],
|
||||
park=park,
|
||||
category=ride_data["category"],
|
||||
opening_date=ride_data["opening_date"],
|
||||
status=ride_data["status"],
|
||||
manufacturer=Manufacturer.objects.get(
|
||||
name=ride_data["manufacturer"]
|
||||
),
|
||||
description=ride_data["description"],
|
||||
)
|
||||
|
||||
# Add ride photos
|
||||
for photo_url in ride_data["photos"]:
|
||||
img_file = self.download_image(photo_url)
|
||||
if img_file:
|
||||
Photo.objects.create(
|
||||
image=img_file,
|
||||
content_type=ContentType.objects.get_for_model(ride),
|
||||
object_id=ride.id,
|
||||
is_primary=True, # First photo is primary
|
||||
)
|
||||
|
||||
# Add coaster stats if present
|
||||
if "stats" in ride_data:
|
||||
RollerCoasterStats.objects.create(
|
||||
ride=ride,
|
||||
height_ft=ride_data["stats"]["height_ft"],
|
||||
length_ft=ride_data["stats"]["length_ft"],
|
||||
speed_mph=ride_data["stats"]["speed_mph"],
|
||||
inversions=ride_data["stats"]["inversions"],
|
||||
ride_time_seconds=ride_data["stats"]["ride_time_seconds"],
|
||||
)
|
||||
|
||||
self.stdout.write(f"Created park and rides: {park.name}")
|
||||
|
||||
except Exception as e:
|
||||
self.stdout.write(self.style.ERROR(f"Error creating park {park_data['name']}: {str(e)}"))
|
||||
continue
|
||||
|
||||
def create_reviews(self):
|
||||
users = list(User.objects.exclude(username="admin"))
|
||||
parks = list(Park.objects.all())
|
||||
|
||||
# Generate random dates within the last year
|
||||
today = datetime.now().date()
|
||||
one_year_ago = today - timedelta(days=365)
|
||||
|
||||
for park in parks:
|
||||
# Create 3-5 reviews per park
|
||||
num_reviews = secrets.SystemRandom().randint(3, 5)
|
||||
for _ in range(num_reviews):
|
||||
# Generate random visit date
|
||||
days_offset = secrets.SystemRandom().randint(0, 365)
|
||||
visit_date = one_year_ago + timedelta(days=days_offset)
|
||||
|
||||
Review.objects.create(
|
||||
user=secrets.choice(users),
|
||||
content_type=ContentType.objects.get_for_model(park),
|
||||
object_id=park.id,
|
||||
title=f"Great experience at {park.name}",
|
||||
content="Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
||||
rating=secrets.SystemRandom().randint(7, 10),
|
||||
visit_date=visit_date,
|
||||
)
|
||||
self.stdout.write(f"Created reviews for {park.name}")
|
||||
@@ -1,9 +1,8 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from operators.models import Operator
|
||||
from parks.models.companies import Operator
|
||||
from parks.models import Park, ParkArea
|
||||
from location.models import Location
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from parks.models.location import ParkLocation
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Seeds initial park data with major theme parks worldwide'
|
||||
@@ -218,18 +217,20 @@ class Command(BaseCommand):
|
||||
# Create location for park
|
||||
if created:
|
||||
loc_data = park_data['location']
|
||||
park_content_type = ContentType.objects.get_for_model(Park)
|
||||
Location.objects.create(
|
||||
content_type=park_content_type,
|
||||
object_id=park.id,
|
||||
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'],
|
||||
latitude=loc_data['latitude'],
|
||||
longitude=loc_data['longitude']
|
||||
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()
|
||||
|
||||
# Create areas for park
|
||||
for area_data in park_data['areas']:
|
||||
|
||||
@@ -1,321 +0,0 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from manufacturers.models import Manufacturer
|
||||
from parks.models import Park
|
||||
from rides.models import Ride, RollerCoasterStats
|
||||
from decimal import Decimal
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Seeds ride data for parks'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Create major ride manufacturers
|
||||
manufacturers_data = [
|
||||
{
|
||||
'name': 'Bolliger & Mabillard',
|
||||
'website': 'https://www.bolligermabillard.com/',
|
||||
'headquarters': 'Monthey, Switzerland',
|
||||
'description': 'Known for their smooth steel roller coasters.'
|
||||
},
|
||||
{
|
||||
'name': 'Rocky Mountain Construction',
|
||||
'website': 'https://www.rockymtnconstruction.com/',
|
||||
'headquarters': 'Hayden, Idaho, USA',
|
||||
'description': 'Specialists in hybrid and steel roller coasters.'
|
||||
},
|
||||
{
|
||||
'name': 'Intamin',
|
||||
'website': 'https://www.intamin.com/',
|
||||
'headquarters': 'Schaan, Liechtenstein',
|
||||
'description': 'Creators of record-breaking roller coasters and rides.'
|
||||
},
|
||||
{
|
||||
'name': 'Vekoma',
|
||||
'website': 'https://www.vekoma.com/',
|
||||
'headquarters': 'Vlodrop, Netherlands',
|
||||
'description': 'Manufacturers of various roller coaster types.'
|
||||
},
|
||||
{
|
||||
'name': 'Mack Rides',
|
||||
'website': 'https://mack-rides.com/',
|
||||
'headquarters': 'Waldkirch, Germany',
|
||||
'description': 'Family-owned manufacturer of roller coasters and attractions.'
|
||||
},
|
||||
{
|
||||
'name': 'Sally Dark Rides',
|
||||
'website': 'https://sallydarkrides.com/',
|
||||
'headquarters': 'Jacksonville, Florida, USA',
|
||||
'description': 'Specialists in dark rides and interactive attractions.'
|
||||
},
|
||||
{
|
||||
'name': 'Zamperla',
|
||||
'website': 'https://www.zamperla.com/',
|
||||
'headquarters': 'Vicenza, Italy',
|
||||
'description': 'Manufacturer of family rides and thrill attractions.'
|
||||
}
|
||||
]
|
||||
|
||||
manufacturers = {}
|
||||
for mfg_data in manufacturers_data:
|
||||
manufacturer, created = Manufacturer.objects.get_or_create(
|
||||
name=mfg_data['name'],
|
||||
defaults=mfg_data
|
||||
)
|
||||
manufacturers[manufacturer.name] = manufacturer
|
||||
self.stdout.write(f'{"Created" if created else "Found"} manufacturer: {manufacturer.name}')
|
||||
|
||||
# Create rides for each park
|
||||
rides_data = [
|
||||
# Silver Dollar City Rides
|
||||
{
|
||||
'park_name': 'Silver Dollar City',
|
||||
'rides': [
|
||||
{
|
||||
'name': 'Time Traveler',
|
||||
'manufacturer': 'Mack Rides',
|
||||
'description': 'The world\'s fastest, steepest, and tallest spinning roller coaster.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2018-03-14',
|
||||
'stats': {
|
||||
'height_ft': 100,
|
||||
'length_ft': 3020,
|
||||
'speed_mph': 50.3,
|
||||
'inversions': 3,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SPINNING',
|
||||
'launch_type': 'LSM'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Wildfire',
|
||||
'manufacturer': 'Bolliger & Mabillard',
|
||||
'description': 'A multi-looping roller coaster with a 155-foot drop.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2001-04-01',
|
||||
'stats': {
|
||||
'height_ft': 155,
|
||||
'length_ft': 3073,
|
||||
'speed_mph': 66,
|
||||
'inversions': 5,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'CHAIN'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Fire In The Hole',
|
||||
'manufacturer': 'Sally Dark Rides',
|
||||
'description': 'Indoor coaster featuring special effects and storytelling.',
|
||||
'category': 'DR',
|
||||
'opening_date': '1972-01-01'
|
||||
},
|
||||
{
|
||||
'name': 'American Plunge',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Log flume ride with a 50-foot splashdown.',
|
||||
'category': 'WR',
|
||||
'opening_date': '1981-01-01'
|
||||
}
|
||||
]
|
||||
},
|
||||
# Magic Kingdom Rides
|
||||
{
|
||||
'park_name': 'Magic Kingdom',
|
||||
'rides': [
|
||||
{
|
||||
'name': 'Space Mountain',
|
||||
'manufacturer': 'Vekoma',
|
||||
'description': 'An indoor roller coaster through space.',
|
||||
'category': 'RC',
|
||||
'opening_date': '1975-01-15',
|
||||
'stats': {
|
||||
'height_ft': 180,
|
||||
'length_ft': 3196,
|
||||
'speed_mph': 27,
|
||||
'inversions': 0,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'CHAIN'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Haunted Mansion',
|
||||
'manufacturer': 'Sally Dark Rides',
|
||||
'description': 'Classic dark ride through a haunted estate.',
|
||||
'category': 'DR',
|
||||
'opening_date': '1971-10-01'
|
||||
},
|
||||
{
|
||||
'name': 'Mad Tea Party',
|
||||
'manufacturer': 'Zamperla',
|
||||
'description': 'Spinning teacup ride based on Alice in Wonderland.',
|
||||
'category': 'FR',
|
||||
'opening_date': '1971-10-01'
|
||||
},
|
||||
{
|
||||
'name': 'Splash Mountain',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Log flume ride with multiple drops and animatronics.',
|
||||
'category': 'WR',
|
||||
'opening_date': '1992-10-02'
|
||||
}
|
||||
]
|
||||
},
|
||||
# Cedar Point Rides
|
||||
{
|
||||
'park_name': 'Cedar Point',
|
||||
'rides': [
|
||||
{
|
||||
'name': 'Millennium Force',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Former world\'s tallest and fastest complete-circuit roller coaster.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2000-05-13',
|
||||
'stats': {
|
||||
'height_ft': 310,
|
||||
'length_ft': 6595,
|
||||
'speed_mph': 93,
|
||||
'inversions': 0,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'CABLE'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Cedar Downs Racing Derby',
|
||||
'manufacturer': 'Zamperla',
|
||||
'description': 'High-speed carousel with racing horses.',
|
||||
'category': 'FR',
|
||||
'opening_date': '1967-01-01'
|
||||
},
|
||||
{
|
||||
'name': 'Snake River Falls',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Shoot-the-Chutes water ride with an 82-foot drop.',
|
||||
'category': 'WR',
|
||||
'opening_date': '1993-05-01'
|
||||
}
|
||||
]
|
||||
},
|
||||
# Universal Studios Florida Rides
|
||||
{
|
||||
'park_name': 'Universal Studios Florida',
|
||||
'rides': [
|
||||
{
|
||||
'name': 'Harry Potter and the Escape from Gringotts',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Indoor steel roller coaster with 3D effects.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2014-07-08',
|
||||
'stats': {
|
||||
'height_ft': 65,
|
||||
'length_ft': 2000,
|
||||
'speed_mph': 50,
|
||||
'inversions': 0,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'LSM'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'The Amazing Adventures of Spider-Man',
|
||||
'manufacturer': 'Sally Dark Rides',
|
||||
'description': 'groundbreaking 3D dark ride.',
|
||||
'category': 'DR',
|
||||
'opening_date': '1999-05-28'
|
||||
},
|
||||
{
|
||||
'name': 'Jurassic World VelociCoaster',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Florida\'s fastest and tallest launch coaster.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2021-06-10',
|
||||
'stats': {
|
||||
'height_ft': 155,
|
||||
'length_ft': 4700,
|
||||
'speed_mph': 70,
|
||||
'inversions': 4,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'LSM'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
# SeaWorld Orlando Rides
|
||||
{
|
||||
'park_name': 'SeaWorld Orlando',
|
||||
'rides': [
|
||||
{
|
||||
'name': 'Mako',
|
||||
'manufacturer': 'Bolliger & Mabillard',
|
||||
'description': 'Orlando\'s tallest, fastest and longest roller coaster.',
|
||||
'category': 'RC',
|
||||
'opening_date': '2016-06-10',
|
||||
'stats': {
|
||||
'height_ft': 200,
|
||||
'length_ft': 4760,
|
||||
'speed_mph': 73,
|
||||
'inversions': 0,
|
||||
'track_material': 'STEEL',
|
||||
'roller_coaster_type': 'SITDOWN',
|
||||
'launch_type': 'CHAIN'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Journey to Atlantis',
|
||||
'manufacturer': 'Mack Rides',
|
||||
'description': 'Water coaster combining dark ride elements with splashes.',
|
||||
'category': 'WR',
|
||||
'opening_date': '1998-03-01'
|
||||
},
|
||||
{
|
||||
'name': 'Sky Tower',
|
||||
'manufacturer': 'Intamin',
|
||||
'description': 'Rotating observation tower providing views of Orlando.',
|
||||
'category': 'TR',
|
||||
'opening_date': '1973-12-15'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
# Create rides and their stats
|
||||
for park_data in rides_data:
|
||||
try:
|
||||
park = Park.objects.get(name=park_data['park_name'])
|
||||
|
||||
for ride_data in park_data['rides']:
|
||||
manufacturer = manufacturers[ride_data['manufacturer']]
|
||||
|
||||
ride, created = Ride.objects.get_or_create(
|
||||
name=ride_data['name'],
|
||||
park=park,
|
||||
defaults={
|
||||
'description': ride_data['description'],
|
||||
'category': ride_data['category'],
|
||||
'manufacturer': manufacturer,
|
||||
'opening_date': ride_data['opening_date'],
|
||||
'status': 'OPERATING'
|
||||
}
|
||||
)
|
||||
self.stdout.write(f'{"Created" if created else "Found"} ride: {ride.name}')
|
||||
|
||||
if created and ride_data.get('stats'):
|
||||
stats = ride_data['stats']
|
||||
RollerCoasterStats.objects.create(
|
||||
ride=ride,
|
||||
height_ft=stats['height_ft'],
|
||||
length_ft=stats['length_ft'],
|
||||
speed_mph=stats['speed_mph'],
|
||||
inversions=stats['inversions'],
|
||||
track_material=stats['track_material'],
|
||||
roller_coaster_type=stats['roller_coaster_type'],
|
||||
launch_type=stats['launch_type']
|
||||
)
|
||||
self.stdout.write(f'Created stats for: {ride.name}')
|
||||
|
||||
except Park.DoesNotExist:
|
||||
self.stdout.write(self.style.WARNING(f'Park not found: {park_data["park_name"]}'))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('Successfully seeded ride data'))
|
||||
119
parks/management/commands/test_location.py
Normal file
119
parks/management/commands/test_location.py
Normal file
@@ -0,0 +1,119 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from parks.models import Park, ParkLocation
|
||||
from parks.models.companies import Company
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Test ParkLocation model functionality'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.stdout.write("🧪 Testing ParkLocation Model Functionality")
|
||||
self.stdout.write("=" * 50)
|
||||
|
||||
# Create a test company (operator)
|
||||
operator, created = Company.objects.get_or_create(
|
||||
name="Test Theme Parks Inc",
|
||||
defaults={
|
||||
'slug': 'test-theme-parks-inc',
|
||||
'roles': ['OPERATOR']
|
||||
}
|
||||
)
|
||||
self.stdout.write(f"✅ Created operator: {operator.name}")
|
||||
|
||||
# Create a test park
|
||||
park, created = Park.objects.get_or_create(
|
||||
name="Test Magic Kingdom",
|
||||
defaults={
|
||||
'slug': 'test-magic-kingdom',
|
||||
'description': 'A test theme park for location testing',
|
||||
'operator': operator
|
||||
}
|
||||
)
|
||||
self.stdout.write(f"✅ Created park: {park.name}")
|
||||
|
||||
# Create a park location
|
||||
location, created = ParkLocation.objects.get_or_create(
|
||||
park=park,
|
||||
defaults={
|
||||
'street_address': '1313 Disneyland Dr',
|
||||
'city': 'Anaheim',
|
||||
'state': 'California',
|
||||
'country': 'USA',
|
||||
'postal_code': '92802',
|
||||
'highway_exit': 'I-5 Exit 110B',
|
||||
'parking_notes': 'Large parking structure available',
|
||||
'seasonal_notes': 'Open year-round'
|
||||
}
|
||||
)
|
||||
self.stdout.write(f"✅ Created location: {location}")
|
||||
|
||||
# Test coordinate setting
|
||||
self.stdout.write("\n🔍 Testing coordinate functionality:")
|
||||
location.set_coordinates(33.8121, -117.9190) # Disneyland coordinates
|
||||
location.save()
|
||||
|
||||
self.stdout.write(f" Latitude: {location.latitude}")
|
||||
self.stdout.write(f" Longitude: {location.longitude}")
|
||||
self.stdout.write(f" Coordinates: {location.coordinates}")
|
||||
self.stdout.write(f" Formatted Address: {location.formatted_address}")
|
||||
|
||||
# Test Park model integration
|
||||
self.stdout.write("\n🔍 Testing Park model integration:")
|
||||
self.stdout.write(f" Park formatted location: {park.formatted_location}")
|
||||
self.stdout.write(f" Park coordinates: {park.coordinates}")
|
||||
|
||||
# Create another location for distance testing
|
||||
operator2, created = Company.objects.get_or_create(
|
||||
name="Six Flags Entertainment",
|
||||
defaults={
|
||||
'slug': 'six-flags-entertainment',
|
||||
'roles': ['OPERATOR']
|
||||
}
|
||||
)
|
||||
|
||||
park2, created = Park.objects.get_or_create(
|
||||
name="Six Flags Magic Mountain",
|
||||
defaults={
|
||||
'slug': 'six-flags-magic-mountain',
|
||||
'description': 'Another test theme park',
|
||||
'operator': operator2
|
||||
}
|
||||
)
|
||||
|
||||
location2, created = ParkLocation.objects.get_or_create(
|
||||
park=park2,
|
||||
defaults={
|
||||
'city': 'Valencia',
|
||||
'state': 'California',
|
||||
'country': 'USA'
|
||||
}
|
||||
)
|
||||
location2.set_coordinates(34.4244, -118.5971) # Six Flags Magic Mountain coordinates
|
||||
location2.save()
|
||||
|
||||
# Test distance calculation
|
||||
self.stdout.write("\n🔍 Testing distance calculation:")
|
||||
distance = location.distance_to(location2)
|
||||
if distance:
|
||||
self.stdout.write(f" Distance between parks: {distance:.2f} km")
|
||||
else:
|
||||
self.stdout.write(" ❌ Distance calculation failed")
|
||||
|
||||
# Test spatial indexing
|
||||
self.stdout.write("\n🔍 Testing spatial queries:")
|
||||
try:
|
||||
from django.contrib.gis.measure import D
|
||||
from django.contrib.gis.geos import Point
|
||||
|
||||
# Find parks within 100km of a point
|
||||
search_point = Point(-117.9190, 33.8121, srid=4326) # Same as Disneyland
|
||||
nearby_locations = ParkLocation.objects.filter(
|
||||
point__distance_lte=(search_point, D(km=100))
|
||||
)
|
||||
self.stdout.write(f" Found {nearby_locations.count()} parks within 100km")
|
||||
for loc in nearby_locations:
|
||||
self.stdout.write(f" - {loc.park.name} in {loc.city}, {loc.state}")
|
||||
except Exception as e:
|
||||
self.stdout.write(f" ⚠️ Spatial queries not fully functional: {e}")
|
||||
|
||||
self.stdout.write("\n✅ ParkLocation model tests completed successfully!")
|
||||
Reference in New Issue
Block a user