from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib import messages from django.utils.decorators import method_decorator from django.views.generic import ListView, DetailView, CreateView from django.urls import reverse_lazy from django.db.models import Prefetch from .models import Deck, DeckCard from store.models import Card, Game def is_pro_user(user): return user.is_authenticated and user.profile.is_pro @login_required def deck_list(request): decks = Deck.objects.filter(user=request.user) return render(request, 'decks/deck_list.html', {'decks': decks}) @user_passes_test(is_pro_user, login_url='users:profile') # Redirect to profile to upgrade def deck_create(request): if request.method == 'POST': name = request.POST.get('name') game_id = request.POST.get('game') game = get_object_or_404(Game, id=game_id) deck = Deck.objects.create(user=request.user, name=name, game=game) messages.success(request, 'Deck created! Start adding cards.') return redirect('decks:deck_builder', deck_id=deck.id) games = Game.objects.all() return render(request, 'decks/deck_create.html', {'games': games}) @user_passes_test(is_pro_user, login_url='users:profile') def deck_builder(request, deck_id): deck = get_object_or_404(Deck, id=deck_id, user=request.user) if request.method == 'POST': # Simple add card logic from search card_id = request.POST.get('card_id') quantity = int(request.POST.get('quantity', 1)) card = get_object_or_404(Card, id=card_id) if card.set.game != deck.game: messages.error(request, 'Cannot add card from different game.') else: deck_card, created = DeckCard.objects.get_or_create(deck=deck, card=card) if not created: deck_card.quantity += quantity else: deck_card.quantity = quantity deck_card.save() messages.success(request, f'Added {card.name}') # Search for cards to add (simplified) search_results = [] query = request.GET.get('q') if query: search_results = Card.objects.filter( set__game=deck.game, name__icontains=query ).select_related('set')[:20] return render(request, 'decks/deck_builder.html', { 'deck': deck, 'search_results': search_results, 'query': query }) @user_passes_test(is_pro_user, login_url='users:profile') def remove_card_from_deck(request, deck_id, card_id): deck = get_object_or_404(Deck, id=deck_id, user=request.user) DeckCard.objects.filter(deck=deck, card_id=card_id).delete() return redirect('decks:deck_builder', deck_id=deck.id) @user_passes_test(is_pro_user, login_url='users:profile') def deck_import(request): if request.method == 'POST': name = request.POST.get('name') game_id = request.POST.get('game') deck_list_text = request.POST.get('deck_list') game = get_object_or_404(Game, id=game_id) # Create Deck deck = Deck.objects.create(user=request.user, name=name, game=game) # Parse Deck List from .utils import parse_deck_list parsed_cards = parse_deck_list(deck_list_text) cards_added = 0 cards_not_found = [] for item in parsed_cards: # Try to find card in the selected game # We strip characters that might be weird or just look for exact match first # Ideally we'd have a better search, but exact match for now # Using iexact for case insensitivity # Simple fuzzy matching could go here, but let's stick to name__iexact for MVP # And also checking if it's in the correct game card_qs = Card.objects.filter( set__game=game, name__iexact=item['name'] ) if not card_qs.exists(): # Try simple cleaning? e.g. remove " // " split cards logic if name search fails? # For now, just report error cards_not_found.append(item['name']) continue card = card_qs.first() # Pick first valid print DeckCard.objects.create( deck=deck, card=card, quantity=item['quantity'], is_sideboard=item['is_sideboard'] ) cards_added += 1 if cards_not_found: messages.warning(request, f"Imported {cards_added} cards. Could not find: {', '.join(cards_not_found[:10])}...") else: messages.success(request, f"Successfully imported deck with {cards_added} cards!") return redirect('decks:deck_builder', deck_id=deck.id) games = Game.objects.all() return render(request, 'decks/deck_import.html', {'games': games})