mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-21 22:31:09 -05:00
here we go
This commit is contained in:
99
parks/management/commands/fix_historical_parks.py
Normal file
99
parks/management/commands/fix_historical_parks.py
Normal file
@@ -0,0 +1,99 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Fix historical park records with null location values'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
with connection.cursor() as cursor:
|
||||
# Make fields nullable temporarily
|
||||
self.stdout.write('Making fields nullable...')
|
||||
cursor.execute("""
|
||||
ALTER TABLE parks_historicalpark
|
||||
ALTER COLUMN city_id DROP NOT NULL,
|
||||
ALTER COLUMN region_id DROP NOT NULL,
|
||||
ALTER COLUMN country_id DROP NOT NULL,
|
||||
ALTER COLUMN location DROP NOT NULL;
|
||||
""")
|
||||
|
||||
# Get or create default locations
|
||||
self.stdout.write('Creating default locations if needed...')
|
||||
|
||||
# Check if Unknown country exists
|
||||
cursor.execute("SELECT id FROM cities_light_country WHERE name = 'Unknown' LIMIT 1;")
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_country (name, name_ascii, slug, geoname_id, alternate_names, display_name, search_names)
|
||||
VALUES ('Unknown', 'Unknown', 'unknown', 0, '', 'Unknown', 'Unknown')
|
||||
RETURNING id;
|
||||
""")
|
||||
default_country_id = cursor.fetchone()[0]
|
||||
else:
|
||||
default_country_id = result[0]
|
||||
|
||||
# Check if Unknown region exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM cities_light_region
|
||||
WHERE name = 'Unknown' AND country_id = %s LIMIT 1;
|
||||
""", [default_country_id])
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_region (name, name_ascii, slug, geoname_id, alternate_names, country_id, display_name, search_names)
|
||||
VALUES ('Unknown', 'Unknown', 'unknown', 0, '', %s, 'Unknown', 'Unknown')
|
||||
RETURNING id;
|
||||
""", [default_country_id])
|
||||
default_region_id = cursor.fetchone()[0]
|
||||
else:
|
||||
default_region_id = result[0]
|
||||
|
||||
# Check if Unknown city exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM cities_light_city
|
||||
WHERE name = 'Unknown' AND region_id = %s LIMIT 1;
|
||||
""", [default_region_id])
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_city (
|
||||
name, name_ascii, slug, geoname_id, alternate_names,
|
||||
region_id, country_id, display_name, search_names,
|
||||
latitude, longitude, population
|
||||
)
|
||||
VALUES (
|
||||
'Unknown', 'Unknown', 'unknown', 0, '',
|
||||
%s, %s, 'Unknown', 'Unknown',
|
||||
0, 0, 0
|
||||
)
|
||||
RETURNING id;
|
||||
""", [default_region_id, default_country_id])
|
||||
default_city_id = cursor.fetchone()[0]
|
||||
else:
|
||||
default_city_id = result[0]
|
||||
|
||||
# Update historical records with null values
|
||||
self.stdout.write('Updating historical records...')
|
||||
cursor.execute("""
|
||||
UPDATE parks_historicalpark
|
||||
SET country_id = %s,
|
||||
region_id = %s,
|
||||
city_id = %s,
|
||||
location = 'Unknown, Unknown, Unknown'
|
||||
WHERE country_id IS NULL
|
||||
OR region_id IS NULL
|
||||
OR city_id IS NULL
|
||||
OR location IS NULL;
|
||||
""", [default_country_id, default_region_id, default_city_id])
|
||||
|
||||
# Make fields non-nullable again
|
||||
self.stdout.write('Making fields non-nullable...')
|
||||
cursor.execute("""
|
||||
ALTER TABLE parks_historicalpark
|
||||
ALTER COLUMN city_id SET NOT NULL,
|
||||
ALTER COLUMN region_id SET NOT NULL,
|
||||
ALTER COLUMN country_id SET NOT NULL,
|
||||
ALTER COLUMN location SET NOT NULL;
|
||||
""")
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('Successfully fixed historical records'))
|
||||
90
parks/management/commands/fix_locations.py
Normal file
90
parks/management/commands/fix_locations.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Fix location fields in parks and historical records'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
with connection.cursor() as cursor:
|
||||
# Check if Unknown country exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM cities_light_country WHERE name = 'Unknown' LIMIT 1;
|
||||
""")
|
||||
result = cursor.fetchone()
|
||||
if result:
|
||||
default_country_id = result[0]
|
||||
else:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_country (name, name_ascii, slug, geoname_id, alternate_names)
|
||||
VALUES ('Unknown', 'Unknown', 'unknown', 0, '')
|
||||
RETURNING id;
|
||||
""")
|
||||
default_country_id = cursor.fetchone()[0]
|
||||
|
||||
# Check if Unknown region exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM cities_light_region
|
||||
WHERE name = 'Unknown' AND country_id = %s LIMIT 1;
|
||||
""", [default_country_id])
|
||||
result = cursor.fetchone()
|
||||
if result:
|
||||
default_region_id = result[0]
|
||||
else:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_region (name, name_ascii, slug, geoname_id, alternate_names, country_id, display_name)
|
||||
VALUES ('Unknown', 'Unknown', 'unknown', 0, '', %s, 'Unknown')
|
||||
RETURNING id;
|
||||
""", [default_country_id])
|
||||
default_region_id = cursor.fetchone()[0]
|
||||
|
||||
# Check if Unknown city exists
|
||||
cursor.execute("""
|
||||
SELECT id FROM cities_light_city
|
||||
WHERE name = 'Unknown' AND region_id = %s LIMIT 1;
|
||||
""", [default_region_id])
|
||||
result = cursor.fetchone()
|
||||
if result:
|
||||
default_city_id = result[0]
|
||||
else:
|
||||
cursor.execute("""
|
||||
INSERT INTO cities_light_city (
|
||||
name, name_ascii, slug, geoname_id, alternate_names,
|
||||
region_id, country_id, display_name,
|
||||
latitude, longitude, population
|
||||
)
|
||||
VALUES (
|
||||
'Unknown', 'Unknown', 'unknown', 0, '',
|
||||
%s, %s, 'Unknown',
|
||||
0, 0, 0
|
||||
)
|
||||
RETURNING id;
|
||||
""", [default_region_id, default_country_id])
|
||||
default_city_id = cursor.fetchone()[0]
|
||||
|
||||
# Update parks with null locations
|
||||
cursor.execute("""
|
||||
UPDATE parks_park
|
||||
SET country_id = %s,
|
||||
region_id = %s,
|
||||
city_id = %s,
|
||||
location = 'Unknown, Unknown, Unknown'
|
||||
WHERE country_id IS NULL
|
||||
OR region_id IS NULL
|
||||
OR city_id IS NULL
|
||||
OR location IS NULL;
|
||||
""", [default_country_id, default_region_id, default_city_id])
|
||||
|
||||
# Update historical records with null locations
|
||||
cursor.execute("""
|
||||
UPDATE parks_historicalpark
|
||||
SET country_id = %s,
|
||||
region_id = %s,
|
||||
city_id = %s,
|
||||
location = 'Unknown, Unknown, Unknown'
|
||||
WHERE country_id IS NULL
|
||||
OR region_id IS NULL
|
||||
OR city_id IS NULL
|
||||
OR location IS NULL;
|
||||
""", [default_country_id, default_region_id, default_city_id])
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('Successfully fixed location fields'))
|
||||
@@ -10,6 +10,11 @@
|
||||
"website": "https://disneyworld.disney.go.com/destinations/magic-kingdom/",
|
||||
"owner": "The Walt Disney Company",
|
||||
"size_acres": 142,
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Walt_Disney_World_Magic_Kingdom_Cinderella_Castle.jpg/1280px-Walt_Disney_World_Magic_Kingdom_Cinderella_Castle.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Magic_Kingdom_Main_Street_USA_Panorama.jpg/1280px-Magic_Kingdom_Main_Street_USA_Panorama.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Magic_Kingdom_-_Cinderella_Castle_at_Night.jpg/1280px-Magic_Kingdom_-_Cinderella_Castle_at_Night.jpg"
|
||||
],
|
||||
"rides": [
|
||||
{
|
||||
"name": "Space Mountain",
|
||||
@@ -18,6 +23,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Walt Disney Imagineering",
|
||||
"description": "A high-speed roller coaster in the dark through space.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Magic_Kingdom_Space_Mountain.jpg/1280px-Magic_Kingdom_Space_Mountain.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Space_Mountain_%28Magic_Kingdom%29_entrance.jpg/1280px-Space_Mountain_%28Magic_Kingdom%29_entrance.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 183,
|
||||
"length_ft": 3196,
|
||||
@@ -33,6 +42,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Walt Disney Imagineering",
|
||||
"description": "A mine train roller coaster through the Old West.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Big_Thunder_Mountain_Railroad_at_Magic_Kingdom.jpg/1280px-Big_Thunder_Mountain_Railroad_at_Magic_Kingdom.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Big_Thunder_Mountain_Railroad_%28Magic_Kingdom%29.jpg/1280px-Big_Thunder_Mountain_Railroad_%28Magic_Kingdom%29.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 104,
|
||||
"length_ft": 2671,
|
||||
@@ -48,6 +61,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Vekoma",
|
||||
"description": "A family roller coaster featuring unique swinging cars.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Seven_Dwarfs_Mine_Train_at_Magic_Kingdom.jpg/1280px-Seven_Dwarfs_Mine_Train_at_Magic_Kingdom.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Seven_Dwarfs_Mine_Train_drop.jpg/1280px-Seven_Dwarfs_Mine_Train_drop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 112,
|
||||
"length_ft": 2000,
|
||||
@@ -62,7 +79,11 @@
|
||||
"opening_date": "1971-10-01",
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Walt Disney Imagineering",
|
||||
"description": "A dark ride through a haunted estate."
|
||||
"description": "A dark ride through a haunted estate.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Haunted_Mansion_at_Magic_Kingdom.jpg/1280px-Haunted_Mansion_at_Magic_Kingdom.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Haunted_Mansion_entrance.jpg/1280px-Haunted_Mansion_entrance.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Pirates of the Caribbean",
|
||||
@@ -70,7 +91,11 @@
|
||||
"opening_date": "1973-12-15",
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Walt Disney Imagineering",
|
||||
"description": "A boat ride through pirate-filled Caribbean waters."
|
||||
"description": "A boat ride through pirate-filled Caribbean waters.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Pirates_of_the_Caribbean_%28Magic_Kingdom%29.jpg/1280px-Pirates_of_the_Caribbean_%28Magic_Kingdom%29.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Pirates_of_the_Caribbean_entrance.jpg/1280px-Pirates_of_the_Caribbean_entrance.jpg"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -84,6 +109,11 @@
|
||||
"website": "https://www.cedarpoint.com",
|
||||
"owner": "Cedar Fair",
|
||||
"size_acres": 364,
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Cedar_Point_aerial_view.jpg/1280px-Cedar_Point_aerial_view.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Cedar_Point_Beach.jpg/1280px-Cedar_Point_Beach.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cedar_Point_at_dusk.jpg/1280px-Cedar_Point_at_dusk.jpg"
|
||||
],
|
||||
"rides": [
|
||||
{
|
||||
"name": "Steel Vengeance",
|
||||
@@ -92,6 +122,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Rocky Mountain Construction",
|
||||
"description": "A hybrid roller coaster featuring multiple inversions.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/Steel_Vengeance_at_Cedar_Point.jpg/1280px-Steel_Vengeance_at_Cedar_Point.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Steel_Vengeance_first_drop.jpg/1280px-Steel_Vengeance_first_drop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 205,
|
||||
"length_ft": 5740,
|
||||
@@ -107,6 +141,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Intamin",
|
||||
"description": "A giga coaster with stunning views of Lake Erie.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Millennium_Force_at_Cedar_Point.jpg/1280px-Millennium_Force_at_Cedar_Point.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Millennium_Force_lift_hill.jpg/1280px-Millennium_Force_lift_hill.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 310,
|
||||
"length_ft": 6595,
|
||||
@@ -122,6 +160,10 @@
|
||||
"status": "SBNO",
|
||||
"manufacturer": "Intamin",
|
||||
"description": "A strata coaster featuring a 420-foot top hat element.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Top_Thrill_Dragster.jpg/1280px-Top_Thrill_Dragster.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/Top_Thrill_Dragster_launch.jpg/1280px-Top_Thrill_Dragster_launch.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 420,
|
||||
"length_ft": 2800,
|
||||
@@ -137,6 +179,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Intamin",
|
||||
"description": "A launched roller coaster with multiple inversions.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Maverick_at_Cedar_Point.jpg/1280px-Maverick_at_Cedar_Point.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Maverick_first_drop.jpg/1280px-Maverick_first_drop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 105,
|
||||
"length_ft": 4450,
|
||||
@@ -157,6 +203,11 @@
|
||||
"website": "https://www.universalorlando.com/web/en/us/theme-parks/islands-of-adventure",
|
||||
"owner": "NBCUniversal",
|
||||
"size_acres": 110,
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Islands_of_Adventure_entrance.jpg/1280px-Islands_of_Adventure_entrance.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Hogwarts_Castle_at_Universal%27s_Islands_of_Adventure.jpg/1280px-Hogwarts_Castle_at_Universal%27s_Islands_of_Adventure.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Port_of_Entry_at_Islands_of_Adventure.jpg/1280px-Port_of_Entry_at_Islands_of_Adventure.jpg"
|
||||
],
|
||||
"rides": [
|
||||
{
|
||||
"name": "Jurassic World VelociCoaster",
|
||||
@@ -165,6 +216,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Intamin",
|
||||
"description": "A high-speed launch coaster featuring velociraptors.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Jurassic_World_VelociCoaster.jpg/1280px-Jurassic_World_VelociCoaster.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/VelociCoaster_top_hat.jpg/1280px-VelociCoaster_top_hat.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 155,
|
||||
"length_ft": 4700,
|
||||
@@ -180,6 +235,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Intamin",
|
||||
"description": "A story coaster through the Forbidden Forest.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Hagrid%27s_Magical_Creatures_Motorbike_Adventure.jpg/1280px-Hagrid%27s_Magical_Creatures_Motorbike_Adventure.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Hagrid%27s_entrance.jpg/1280px-Hagrid%27s_entrance.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 65,
|
||||
"length_ft": 5053,
|
||||
@@ -194,7 +253,11 @@
|
||||
"opening_date": "1999-05-28",
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Oceaneering International",
|
||||
"description": "A 3D dark ride featuring Spider-Man."
|
||||
"description": "A 3D dark ride featuring Spider-Man.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/The_Amazing_Adventures_of_Spider-Man.jpg/1280px-The_Amazing_Adventures_of_Spider-Man.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Spider-Man_ride_entrance.jpg/1280px-Spider-Man_ride_entrance.jpg"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -208,6 +271,11 @@
|
||||
"website": "https://www.altontowers.com",
|
||||
"owner": "Merlin Entertainments",
|
||||
"size_acres": 910,
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Alton_Towers_aerial_view.jpg/1280px-Alton_Towers_aerial_view.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Alton_Towers_mansion.jpg/1280px-Alton_Towers_mansion.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Alton_Towers_gardens.jpg/1280px-Alton_Towers_gardens.jpg"
|
||||
],
|
||||
"rides": [
|
||||
{
|
||||
"name": "Nemesis",
|
||||
@@ -216,6 +284,10 @@
|
||||
"status": "CLOSED",
|
||||
"manufacturer": "Bolliger & Mabillard",
|
||||
"description": "An inverted roller coaster through ravines.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Nemesis_at_Alton_Towers.jpg/1280px-Nemesis_at_Alton_Towers.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Nemesis_loop.jpg/1280px-Nemesis_loop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 43,
|
||||
"length_ft": 2349,
|
||||
@@ -231,6 +303,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Bolliger & Mabillard",
|
||||
"description": "The world's first vertical drop roller coaster.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Oblivion_at_Alton_Towers.jpg/1280px-Oblivion_at_Alton_Towers.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Oblivion_vertical_drop.jpg/1280px-Oblivion_vertical_drop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 65,
|
||||
"length_ft": 1804,
|
||||
@@ -251,6 +327,11 @@
|
||||
"website": "https://www.europapark.de",
|
||||
"owner": "Mack Rides",
|
||||
"size_acres": 235,
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Europa-Park_entrance.jpg/1280px-Europa-Park_entrance.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Europa-Park_aerial_view.jpg/1280px-Europa-Park_aerial_view.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Europa-Park_at_night.jpg/1280px-Europa-Park_at_night.jpg"
|
||||
],
|
||||
"rides": [
|
||||
{
|
||||
"name": "Silver Star",
|
||||
@@ -259,6 +340,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Bolliger & Mabillard",
|
||||
"description": "A hypercoaster with stunning views.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Silver_Star_at_Europa-Park.jpg/1280px-Silver_Star_at_Europa-Park.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Silver_Star_first_drop.jpg/1280px-Silver_Star_first_drop.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 239,
|
||||
"length_ft": 4003,
|
||||
@@ -274,6 +359,10 @@
|
||||
"status": "OPERATING",
|
||||
"manufacturer": "Mack Rides",
|
||||
"description": "A launched roller coaster with multiple inversions.",
|
||||
"photos": [
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Blue_Fire_at_Europa-Park.jpg/1280px-Blue_Fire_at_Europa-Park.jpg",
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Blue_Fire_launch.jpg/1280px-Blue_Fire_launch.jpg"
|
||||
],
|
||||
"stats": {
|
||||
"height_ft": 125,
|
||||
"length_ft": 3465,
|
||||
@@ -285,4 +374,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ from faker import Faker
|
||||
import requests
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
from cities_light.models import City, Country
|
||||
|
||||
from parks.models import Park
|
||||
from rides.models import Ride, RollerCoasterStats
|
||||
@@ -30,25 +31,30 @@ class Command(BaseCommand):
|
||||
parser.add_argument('--users', type=int, default=50)
|
||||
parser.add_argument('--reviews-per-item', type=int, default=10)
|
||||
|
||||
def download_and_save_image(self, url, prefix):
|
||||
def download_and_save_image(self, url):
|
||||
try:
|
||||
response = requests.get(url)
|
||||
img = Image.open(BytesIO(response.content))
|
||||
img_io = BytesIO()
|
||||
img.save(img_io, format='JPEG')
|
||||
img_io.seek(0)
|
||||
return f'{prefix}_{fake.uuid4()}.jpg', File(img_io)
|
||||
except:
|
||||
filename = url.split('/')[-1]
|
||||
return filename, File(img_io)
|
||||
except Exception as e:
|
||||
self.stdout.write(self.style.WARNING(f'Failed to download image {url}: {str(e)}'))
|
||||
return None, None
|
||||
|
||||
def create_users(self, count):
|
||||
self.stdout.write('Creating users...')
|
||||
users = []
|
||||
|
||||
# Get existing admin user
|
||||
admin_user = User.objects.get(username='admin')
|
||||
users.append(admin_user)
|
||||
self.stdout.write('Added existing admin user')
|
||||
try:
|
||||
# Get existing admin user
|
||||
admin_user = User.objects.get(username='admin')
|
||||
users.append(admin_user)
|
||||
self.stdout.write('Added existing admin user')
|
||||
except User.DoesNotExist:
|
||||
self.stdout.write(self.style.WARNING('Admin user not found, skipping...'))
|
||||
|
||||
# Create regular users using raw SQL
|
||||
roles = ['USER'] * 20 + ['MODERATOR'] * 3 + ['ADMIN'] * 2
|
||||
@@ -232,72 +238,87 @@ class Command(BaseCommand):
|
||||
|
||||
parks = []
|
||||
for park_data in seed_data['parks']:
|
||||
# Create park with company instance
|
||||
park = Park.objects.create(
|
||||
name=park_data['name'],
|
||||
slug=slugify(park_data['name']),
|
||||
location=park_data['location'],
|
||||
country=park_data['country'],
|
||||
opening_date=datetime.strptime(park_data['opening_date'], '%Y-%m-%d').date(),
|
||||
status=park_data['status'],
|
||||
description=park_data['description'],
|
||||
website=park_data['website'],
|
||||
owner=companies[park_data['owner']],
|
||||
size_acres=park_data['size_acres']
|
||||
)
|
||||
|
||||
# Add park photos
|
||||
for _ in range(random.randint(2, 5)):
|
||||
img_url = f'https://picsum.photos/800/600?random={fake.random_number(5)}'
|
||||
filename, file = self.download_and_save_image(img_url, 'park')
|
||||
if filename and file:
|
||||
Photo.objects.create(
|
||||
content_object=park,
|
||||
image=file,
|
||||
uploaded_by=random.choice(users),
|
||||
caption=fake.sentence(),
|
||||
is_approved=True
|
||||
)
|
||||
|
||||
# Create rides for this park
|
||||
for ride_data in park_data['rides']:
|
||||
ride = Ride.objects.create(
|
||||
name=ride_data['name'],
|
||||
slug=slugify(ride_data['name']),
|
||||
category=ride_data['category'],
|
||||
park=park,
|
||||
status=ride_data['status'],
|
||||
opening_date=datetime.strptime(ride_data['opening_date'], '%Y-%m-%d').date(),
|
||||
manufacturer=manufacturers[ride_data['manufacturer']],
|
||||
description=ride_data['description']
|
||||
try:
|
||||
# Get country from cities_light
|
||||
country = Country.objects.get(code2=park_data['country'])
|
||||
|
||||
# Try to find city, but don't require it
|
||||
city = None
|
||||
try:
|
||||
city_name = park_data['location'].split(',')[0].strip()
|
||||
city = City.objects.filter(name__iexact=city_name, country=country).first()
|
||||
except:
|
||||
self.stdout.write(self.style.WARNING(f'City not found for {park_data["name"]}, using location text'))
|
||||
|
||||
# Create park
|
||||
park = Park.objects.create(
|
||||
name=park_data['name'],
|
||||
slug=slugify(park_data['name']),
|
||||
location=park_data['location'],
|
||||
country=country,
|
||||
city=city,
|
||||
opening_date=datetime.strptime(park_data['opening_date'], '%Y-%m-%d').date(),
|
||||
status=park_data['status'],
|
||||
description=park_data['description'],
|
||||
website=park_data['website'],
|
||||
owner=companies[park_data['owner']],
|
||||
size_acres=park_data['size_acres']
|
||||
)
|
||||
|
||||
# Add roller coaster stats if applicable
|
||||
if ride_data['category'] == 'RC' and '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']
|
||||
)
|
||||
|
||||
# Add ride photos
|
||||
for _ in range(random.randint(2, 5)):
|
||||
img_url = f'https://picsum.photos/800/600?random={fake.random_number(5)}'
|
||||
filename, file = self.download_and_save_image(img_url, 'ride')
|
||||
# Add park photos
|
||||
for photo_url in park_data.get('photos', []):
|
||||
filename, file = self.download_and_save_image(photo_url)
|
||||
if filename and file:
|
||||
Photo.objects.create(
|
||||
content_object=ride,
|
||||
content_object=park,
|
||||
image=file,
|
||||
uploaded_by=random.choice(users),
|
||||
caption=fake.sentence(),
|
||||
caption=f"Photo of {park.name}",
|
||||
is_approved=True
|
||||
)
|
||||
|
||||
# Create rides for this park
|
||||
for ride_data in park_data['rides']:
|
||||
ride = Ride.objects.create(
|
||||
name=ride_data['name'],
|
||||
slug=slugify(ride_data['name']),
|
||||
category=ride_data['category'],
|
||||
park=park,
|
||||
status=ride_data['status'],
|
||||
opening_date=datetime.strptime(ride_data['opening_date'], '%Y-%m-%d').date(),
|
||||
manufacturer=manufacturers[ride_data['manufacturer']],
|
||||
description=ride_data['description']
|
||||
)
|
||||
|
||||
# Add roller coaster stats if applicable
|
||||
if ride_data['category'] == 'RC' and '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']
|
||||
)
|
||||
|
||||
# Add ride photos
|
||||
for photo_url in ride_data.get('photos', []):
|
||||
filename, file = self.download_and_save_image(photo_url)
|
||||
if filename and file:
|
||||
Photo.objects.create(
|
||||
content_object=ride,
|
||||
image=file,
|
||||
uploaded_by=random.choice(users),
|
||||
caption=f"Photo of {ride.name}",
|
||||
is_approved=True
|
||||
)
|
||||
|
||||
parks.append(park)
|
||||
self.stdout.write(f'Created park and rides: {park.name}')
|
||||
|
||||
parks.append(park)
|
||||
self.stdout.write(f'Created park and rides: {park.name}')
|
||||
except Exception as e:
|
||||
self.stdout.write(self.style.ERROR(f'Failed to create park {park_data["name"]}: {str(e)}'))
|
||||
continue
|
||||
|
||||
return parks
|
||||
|
||||
|
||||
Reference in New Issue
Block a user