pkmntrade.club/cards/views.py

169 lines
6.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.views.generic import TemplateView
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView, CreateView, ListView, DetailView
from cards.models import Card
from trades.models import TradeOffer
class CardDetailView(DetailView):
model = Card
template_name = "cards/card_detail.html"
context_object_name = "card"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
card = self.get_object()
# Count of trade offers where the card appears as a "have" in a trade.
context['trade_offer_have_count'] = TradeOffer.objects.filter(
trade_offer_have_cards__card=card
).distinct().count()
# Count of trade offers where the card appears as a "want" in a trade.
context['trade_offer_want_count'] = TradeOffer.objects.filter(
trade_offer_want_cards__card=card
).distinct().count()
return context
class TradeOfferHaveCardListView(ListView):
model = TradeOffer
template_name = "cards/_trade_offer_list.html"
context_object_name = "trade_offers"
paginate_by = 6
def get_queryset(self):
card_id = self.kwargs.get("pk")
order_param = self.request.GET.get("order", "newest")
ordering = "-updated_at" if order_param == "newest" else "updated_at"
return TradeOffer.objects.filter(
trade_offer_have_cards__card_id=card_id
).order_by(ordering).distinct()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['side'] = 'have'
return context
class TradeOfferWantCardListView(ListView):
model = TradeOffer
template_name = "cards/_trade_offer_list.html"
context_object_name = "trade_offers"
paginate_by = 6
def get_queryset(self):
card_id = self.kwargs.get("pk")
order_param = self.request.GET.get("order", "newest")
ordering = "-updated_at" if order_param == "newest" else "updated_at"
return TradeOffer.objects.filter(
trade_offer_want_cards__card_id=card_id
).order_by(ordering).distinct()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['side'] = 'want'
return context
class CardListView(ListView):
model = Card
paginate_by = 100 # For non-grouped mode; grouping mode will override default pagination.
context_object_name = "cards"
def get_template_names(self):
if self.request.headers.get("x-requested-with") == "XMLHttpRequest":
return ["cards/_card_list.html"]
return ["cards/card_list.html"]
def get_ordering(self):
order = self.request.GET.get("order", "absolute")
if order == "alphabetical":
return "name"
elif order == "rarity":
return "-rarity_level"
else: # absolute ordering
return "id"
def get_queryset(self):
qs = super().get_queryset()
ordering = self.get_ordering()
qs = qs.order_by(ordering)
return qs.prefetch_related("decks").distinct()
def get_paginate_by(self, queryset):
group_by = self.request.GET.get("group_by")
if group_by in ("deck", "cardset", "rarity"):
# When grouping is enabled, we want to paginate manually so disable default pagination.
return None
return self.paginate_by
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
order = self.request.GET.get("order", "absolute")
group_by = self.request.GET.get("group_by")
context["order"] = order
context["group_by"] = group_by
if group_by in ("deck", "cardset", "rarity"):
# Fetch the complete queryset (no slicing)
full_qs = self.get_queryset()
all_cards = list(full_qs)
flat_cards = []
if group_by == "deck":
# Each card may belong to multiple decks reproduce the existing logic.
for card in all_cards:
for deck in card.decks.all():
flat_cards.append({"group": deck.name, "card": card})
flat_cards.sort(key=lambda x: x["group"].lower())
elif group_by == "cardset":
for card in all_cards:
flat_cards.append({"group": card.cardset, "card": card})
flat_cards.sort(key=lambda x: x["group"].lower())
elif group_by == "rarity":
for card in all_cards:
flat_cards.append({"group": card.rarity_level, "card": card})
flat_cards.sort(key=lambda x: x["group"], reverse=True)
total_cards = len(flat_cards)
try:
page_number = int(self.request.GET.get("page", 1))
if page_number < 1:
page_number = 1
except ValueError:
page_number = 1
per_page = 96
start = (page_number - 1) * per_page
end = page_number * per_page
page_flat_cards = flat_cards[start:end]
# Reassemble the flat list into grouped structure for just this page.
page_groups = []
for item in page_flat_cards:
group_value = item["group"]
card_obj = item["card"]
if page_groups and page_groups[-1]["group"] == group_value:
page_groups[-1]["cards"].append(card_obj)
else:
page_groups.append({"group": group_value, "cards": [card_obj]})
context["groups"] = page_groups
# Set up custom pagination context.
from math import ceil
num_pages = ceil(total_cards / per_page)
page_obj = {
"number": page_number,
"has_previous": page_number > 1,
"has_next": page_number < num_pages,
"previous_page_number": page_number - 1 if page_number > 1 else None,
"next_page_number": page_number + 1 if page_number < num_pages else None,
"paginator": {
"num_pages": num_pages,
},
}
context["page_obj"] = page_obj
context["is_paginated"] = total_cards > per_page
context["total_cards"] = total_cards
# Optionally, keep the full queryset in object_list.
context["object_list"] = full_qs
return context
return context