169 lines
6.5 KiB
Python
169 lines
6.5 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
|
||
|
||
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
|