pkmntrade.club/cards/views.py

161 lines
No EOL
6.4 KiB
Python

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
from cards.mixins import ReusablePaginationMixin
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(ReusablePaginationMixin, ListView):
model = Card
paginate_by = 36 # 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"):
full_qs = self.get_queryset()
all_cards = list(full_qs)
flat_cards = []
if group_by == "deck":
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_icon, "sort_group": card.rarity_level, "card": card})
flat_cards.sort(key=lambda x: x["sort_group"], reverse=True)
try:
page_number = int(self.request.GET.get("page", 1))
except ValueError:
page_number = 1
# Use our custom mixin logic here
self.per_page = 36
page_flat_cards, pagination_context = self.paginate_data(flat_cards, page_number)
# Reassemble the flat list into groups for the current 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
context["page_obj"] = pagination_context
context["total_cards"] = len(flat_cards)
context["object_list"] = full_qs
return context
else:
# For non-grouped mode, transform the built-in paginator page
if "page_obj" in context:
page = context["page_obj"]
# Create a unified pagination context dict with updated keys
custom_page_obj = {
"number": page.number,
"has_previous": page.has_previous(),
"has_next": page.has_next(),
"previous_page_number": page.previous_page_number() if page.has_previous() else 1,
"next_page_number": page.next_page_number() if page.has_next() else page.paginator.num_pages,
"paginator": {"num_pages": page.paginator.num_pages},
}
context["page_obj"] = custom_page_obj
return context