import random import requests from django.core.management import call_command from django.core.management.base import BaseCommand from django.utils.text import slugify from django.contrib.auth import get_user_model from store.models import Game, Set, Card, CardListing, Seller User = get_user_model() class Command(BaseCommand): help = 'Populate database with specific test stores and listings, leveraging external scripts for card data.' def handle(self, *args, **options): self.stdout.write('Starting database population...') # 1. Ensure Games and Cards exist self.ensure_games_populated() # 2. Get Game Objects try: mtg = Game.objects.get(slug='magic-the-gathering') pokemon = Game.objects.get(slug='pokemon-tcg') lorcana = Game.objects.get(slug='disney-lorcana') except Game.DoesNotExist as e: self.stdout.write(self.style.ERROR(f"Missing a required game after population attempts! {e}")) return # 3. Create Stores self.create_stores_and_listings(mtg, pokemon, lorcana) self.stdout.write(self.style.SUCCESS('Database population complete!')) def ensure_games_populated(self): # MTG - Native (kept simple from original) or call a script if we had one. # Since the original had MTG logic, I'll keep a simplified version here or call it if I haven't deleted it. # But wait, I'm replacing the whole file. I should probably keep the MTG fetcher or rely on what's there? # The prompt implies I should just "overhaul" it. I'll re-implement a robust MTG fetcher or reuse the old one's logic if I want # but to be safe and clean, I'll just check if cards exist, if not, fetch some. # Check MTG if not Game.objects.filter(slug='magic-the-gathering').exists() or not Card.objects.filter(set__game__slug='magic-the-gathering').exists(): self.stdout.write("Populating MTG Cards...") self.populate_mtg() else: self.stdout.write("MTG cards found, skipping population.") # Check Pokemon if not Game.objects.filter(slug='pokemon-tcg').exists() or not Card.objects.filter(set__game__slug='pokemon-tcg').exists(): self.stdout.write("Populating Pokemon Cards via script...") call_command('populate_pokemon_cards') else: self.stdout.write("Pokemon cards found, skipping population.") # Check Lorcana if not Game.objects.filter(slug='disney-lorcana').exists() or not Card.objects.filter(set__game__slug='disney-lorcana').exists(): self.stdout.write("Populating Lorcana Cards via script...") call_command('populate_lorcana_cards') else: self.stdout.write("Lorcana cards found, skipping population.") def populate_mtg(self): # Simplified reused logic from original game, _ = Game.objects.get_or_create( slug='magic-the-gathering', defaults={'name': 'Magic: The Gathering'} ) sets_api = "https://api.scryfall.com/sets" try: resp = requests.get(sets_api).json() target_sets = [s for s in resp['data'] if s['set_type'] == 'expansion'][:3] for s_data in target_sets: set_obj, _ = Set.objects.get_or_create( game=game, name=s_data['name'], code=s_data['code'], defaults={'release_date': s_data.get('released_at')} ) cards_url = s_data['search_uri'] cards_resp = requests.get(cards_url).json() for card_data in cards_resp.get('data', [])[:50]: image = None if 'image_uris' in card_data: image = card_data['image_uris'].get('normal') elif 'card_faces' in card_data and 'image_uris' in card_data['card_faces'][0]: image = card_data['card_faces'][0]['image_uris'].get('normal') if not image: continue Card.objects.get_or_create( set=set_obj, name=card_data['name'], collector_number=card_data['collector_number'], defaults={ 'rarity': card_data['rarity'].capitalize(), 'image_url': image, 'scryfall_id': card_data['id'], 'tcgplayer_id': card_data.get('tcgplayer_id'), } ) except Exception as e: self.stdout.write(self.style.ERROR(f"Error populating MTG: {e}")) def create_stores_and_listings(self, mtg, pokemon, lorcana): # Define Store Configs stores_config = [ # Store 1: 100 Magic the gathering single card listings { 'name': 'Mystic Magic', 'slug': 'mystic-magic', 'listings': [(mtg, 100)] }, # Store 2: 80 lorcana single card listings { 'name': 'Inkborn Illumineers', 'slug': 'inkborn-illumineers', 'listings': [(lorcana, 80)] }, # Store 3: 200 pokemon single card listings { 'name': 'Poke Mart', 'slug': 'poke-mart', 'listings': [(pokemon, 200)] }, # Store 4: 50 Magic the gathering and lorcana listings (Split 25/25) { 'name': 'Wizards and Wanderers', 'slug': 'wizards-and-wanderers', 'listings': [(mtg, 25), (lorcana, 25)] }, # Store 5: 40 Magic the gathering and 20 pokemon listings { 'name': 'Mana & Mons', 'slug': 'mana-and-mons', 'listings': [(mtg, 40), (pokemon, 20)] }, # Store 6: 100 lorcana and 10 pokemon listings { 'name': 'Disney Duelists', 'slug': 'disney-duelists', 'listings': [(lorcana, 100), (pokemon, 10)] }, # Store 7: 100 cards for all three games (Split ~33 each) { 'name': 'The Collector Trove', 'slug': 'collector-trove', 'listings': [(mtg, 33), (lorcana, 33), (pokemon, 34)] } ] for config in stores_config: self.stdout.write(f"Setting up store: {config['name']}...") # Create User and Seller username = config['slug'].replace('-', '') user, created = User.objects.get_or_create(username=username, defaults={'email': f"{username}@example.com"}) if created: user.set_password('password') user.save() seller, _ = Seller.objects.get_or_create( user=user, defaults={ 'store_name': config['name'], 'slug': config['slug'], 'description': f"Welcome to {config['name']}!", 'contact_email': f"{username}@example.com" } ) # Create Listings for game, count in config['listings']: self.create_listings_for_store(seller, game, count) def create_listings_for_store(self, seller, game, count): cards = list(Card.objects.filter(set__game=game)) if not cards: self.stdout.write(self.style.WARNING(f"No cards found for {game.name}, cannot create listings.")) return listing_count = 0 while listing_count < count: card = random.choice(cards) # Randomize attributes price = round(random.uniform(1.00, 150.00), 2) quantity = random.randint(1, 10) condition = random.choice(['NM', 'LP', 'MP', 'HP']) CardListing.objects.create( card=card, seller=seller, price=price, quantity=quantity, condition=condition, status='listed' ) listing_count += 1 self.stdout.write(f" - Created {count} listings for {game.name}")