pkmntrade.club/home/views.py

71 lines
No EOL
3 KiB
Python

from collections import defaultdict
from django.views.generic import TemplateView
from django.urls import reverse_lazy
from django.db.models import Count, Q, Prefetch, Sum, F, IntegerField, Value, BooleanField, Case, When
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from trades.models import TradeOffer, TradeAcceptance, TradeOfferHaveCard, TradeOfferWantCard
from cards.models import Card, CardSet, Rarity
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from django.template.response import TemplateResponse
from django.http import HttpResponseRedirect
@method_decorator(cache_page(60), name='get')
class HomePageView(TemplateView):
template_name = "home/home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["cards"] = Card.objects.all().order_by("name", "rarity__pk")
# Reuse base trade offer queryset for market stats
base_offer_qs = TradeOffer.objects.filter(is_closed=False)
# Recent Offers
recent_offers_qs = base_offer_qs.order_by("-created_at")
context["recent_offers"] = recent_offers_qs[:6]
# Most Offered Cards
context["most_offered_cards"] = (
Card.objects_no_prefetch.filter(tradeofferhavecard__isnull=False)
.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
.order_by("-offer_count", "?")[:6]
)
# Most Wanted Cards
context["most_wanted_cards"] = (
Card.objects_no_prefetch.filter(tradeofferwantcard__isnull=False)
.annotate(offer_count=Sum("tradeofferwantcard__quantity"))
.order_by("-offer_count", "?")[:6]
)
# Least Offered Cards
context["least_offered_cards"] = (
Card.objects_no_prefetch.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
.order_by("offer_count", "?")[:6]
)
featured = {}
featured["All"] = base_offer_qs.order_by("created_at")[:6]
normalized_ids = list(
Rarity.objects.filter(pk__lte=5).values_list("normalized_id", flat=True).distinct()
)
rarity_map = {rarity.normalized_id: rarity.icons for rarity in Rarity.objects.filter(pk__lte=5)}
# For each normalized id (sorted descending), filter base offers that have a related card with that rarity.
for norm in sorted(normalized_ids, reverse=True):
offers_qs = base_offer_qs.filter(
have_cards__rarity__normalized_id=norm
# or want cards, but all offers share the same rarity so checking have_cards is enough
# TODO: attach rarity to offer so we don't need to do this
).order_by("created_at").distinct()[:6]
icon_label = rarity_map.get(norm)
if icon_label:
featured[icon_label] = offers_qs
context["featured_offers"] = featured
return context