finished conversion to tailwind
This commit is contained in:
parent
6e2843c60e
commit
d62956d465
50 changed files with 2490 additions and 1273 deletions
194
home/views.py
194
home/views.py
|
|
@ -1,32 +1,32 @@
|
|||
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
|
||||
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
|
||||
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') # Cache view for 60 seconds
|
||||
@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)
|
||||
|
||||
# Use POST data if available, else fallback to GET
|
||||
request_data = self.request.POST if self.request.method == "POST" else self.request.GET
|
||||
def get_base_trade_offer_queryset(self):
|
||||
"""
|
||||
Returns a queryset for TradeOffer that includes prefetches and denormalized aggregates.
|
||||
"""
|
||||
active_states = [
|
||||
TradeAcceptance.AcceptanceState.ACCEPTED,
|
||||
TradeAcceptance.AcceptanceState.SENT,
|
||||
TradeAcceptance.AcceptanceState.RECEIVED,
|
||||
TradeAcceptance.AcceptanceState.THANKED_BY_INITIATOR,
|
||||
TradeAcceptance.AcceptanceState.THANKED_BY_ACCEPTOR,
|
||||
TradeAcceptance.AcceptanceState.THANKED_BY_BOTH,
|
||||
]
|
||||
|
||||
# --- Search form logic ---
|
||||
offered_cards = request_data.getlist("offered_cards")
|
||||
wanted_cards = request_data.getlist("wanted_cards")
|
||||
context["offered_cards"] = offered_cards
|
||||
context["wanted_cards"] = wanted_cards
|
||||
|
||||
# Define prefetch objects ordered by number of associated trade offers ascending,
|
||||
# and by id secondarily.
|
||||
have_cards_prefetch = Prefetch(
|
||||
'have_cards',
|
||||
queryset=Card.objects.annotate(
|
||||
|
|
@ -40,11 +40,9 @@ class HomePageView(TemplateView):
|
|||
).order_by("trade_offer_count", "id")
|
||||
)
|
||||
|
||||
search_results = None
|
||||
if offered_cards or wanted_cards:
|
||||
# Instead of filtering by a 'state' field (which no longer exists),
|
||||
# we fetch all offers. You may later add logic to filter only "open" offers.
|
||||
qs = TradeOffer.objects.all().prefetch_related(
|
||||
qs = (
|
||||
TradeOffer.objects.all()
|
||||
.prefetch_related(
|
||||
have_cards_prefetch,
|
||||
"have_cards__decks",
|
||||
"have_cards__rarity",
|
||||
|
|
@ -52,116 +50,80 @@ class HomePageView(TemplateView):
|
|||
want_cards_prefetch,
|
||||
"want_cards__decks",
|
||||
"want_cards__rarity",
|
||||
"want_cards__cardset"
|
||||
).select_related(
|
||||
"initiated_by__user"
|
||||
"want_cards__cardset",
|
||||
"acceptances"
|
||||
)
|
||||
if offered_cards:
|
||||
try:
|
||||
offered_card_ids = [int(card) for card in offered_cards]
|
||||
except ValueError:
|
||||
qs = qs.none()
|
||||
else:
|
||||
qs = qs.filter(want_cards__id__in=offered_card_ids)
|
||||
if wanted_cards:
|
||||
try:
|
||||
wanted_card_ids = [int(card) for card in wanted_cards]
|
||||
except ValueError:
|
||||
qs = qs.none()
|
||||
else:
|
||||
qs = qs.filter(have_cards__id__in=wanted_card_ids)
|
||||
|
||||
page_number = request_data.get("page", 1)
|
||||
paginator = Paginator(qs, 6)
|
||||
try:
|
||||
search_results = paginator.page(page_number)
|
||||
except PageNotAnInteger:
|
||||
search_results = paginator.page(1)
|
||||
except EmptyPage:
|
||||
search_results = paginator.page(paginator.num_pages)
|
||||
|
||||
context["search_results"] = search_results
|
||||
|
||||
# --- Recently posted offers (latest 5, newest first) ---
|
||||
context["recent_offers"] = TradeOffer.objects.order_by("-created_at").prefetch_related(
|
||||
have_cards_prefetch,
|
||||
"have_cards__decks",
|
||||
"have_cards__rarity",
|
||||
"have_cards__cardset",
|
||||
want_cards_prefetch,
|
||||
"want_cards__decks",
|
||||
"want_cards__rarity",
|
||||
"want_cards__cardset"
|
||||
).select_related(
|
||||
"initiated_by__user"
|
||||
)[:5]
|
||||
|
||||
# --- Most offered cards ---
|
||||
context["most_offered_cards"] = Card.objects.filter(
|
||||
tradeofferhavecard__isnull=False
|
||||
).annotate(
|
||||
offer_count=Sum("tradeofferhavecard__quantity")
|
||||
).order_by("-offer_count").select_related("rarity", "cardset").prefetch_related("decks")[:5]
|
||||
|
||||
# --- Most wanted cards ---
|
||||
context["most_wanted_cards"] = Card.objects.filter(
|
||||
tradeofferwantcard__isnull=False
|
||||
).annotate(
|
||||
offer_count=Sum("tradeofferwantcard__quantity")
|
||||
).order_by("-offer_count").select_related("rarity", "cardset").prefetch_related("decks")[:5]
|
||||
|
||||
# --- Least offered cards ---
|
||||
context["least_offered_cards"] = Card.objects.annotate(
|
||||
offer_count=Sum("tradeofferhavecard__quantity")
|
||||
).order_by("offer_count", "?")[:5]
|
||||
|
||||
# --- Featured offers grouped by rarity (using card.rarity.icon for tab names) ---
|
||||
featured = {}
|
||||
all_offers = list(
|
||||
TradeOffer.objects.order_by("created_at").prefetch_related(
|
||||
have_cards_prefetch,
|
||||
"have_cards__decks",
|
||||
"have_cards__rarity",
|
||||
"have_cards__cardset",
|
||||
want_cards_prefetch,
|
||||
"want_cards__decks",
|
||||
"want_cards__rarity",
|
||||
"want_cards__cardset"
|
||||
).select_related(
|
||||
"initiated_by__user"
|
||||
.select_related("initiated_by__user")
|
||||
.annotate(
|
||||
is_active=Case(
|
||||
When(
|
||||
Q(total_have_accepted__lt=F('total_have_quantity')) &
|
||||
Q(total_want_accepted__lt=F('total_want_quantity')),
|
||||
then=Value(True)
|
||||
),
|
||||
default=Value(False),
|
||||
output_field=BooleanField()
|
||||
)
|
||||
)
|
||||
)
|
||||
featured["All"] = all_offers[:5]
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
# Add available_cards QuerySet so card_multiselect works properly.
|
||||
context["available_cards"] = Card.objects.all() \
|
||||
.order_by("name", "rarity__pk") \
|
||||
.select_related("rarity", "cardset") \
|
||||
.prefetch_related("decks")
|
||||
|
||||
# Group offers by normalized rarity id from their have_cards
|
||||
# Reuse base trade offer queryset for market stats
|
||||
base_offer_qs = self.get_base_trade_offer_queryset().filter(manually_closed=False, is_active=True)
|
||||
|
||||
# Recent Offers
|
||||
recent_offers_qs = base_offer_qs.order_by("-created_at")[:10]
|
||||
context["recent_offers"] = list(recent_offers_qs)[:5]
|
||||
|
||||
# Most Offered Cards
|
||||
context["most_offered_cards"] = (
|
||||
Card.objects.filter(tradeofferhavecard__isnull=False)
|
||||
.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
|
||||
.order_by("-offer_count")
|
||||
.select_related("rarity", "cardset")
|
||||
.prefetch_related("decks")[:5]
|
||||
)
|
||||
|
||||
# Most Wanted Cards
|
||||
context["most_wanted_cards"] = (
|
||||
Card.objects.filter(tradeofferwantcard__isnull=False)
|
||||
.annotate(offer_count=Sum("tradeofferwantcard__quantity"))
|
||||
.order_by("-offer_count")
|
||||
.select_related("rarity", "cardset")
|
||||
.prefetch_related("decks")[:5]
|
||||
)
|
||||
|
||||
# Least Offered Cards
|
||||
context["least_offered_cards"] = (
|
||||
Card.objects.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
|
||||
.order_by("offer_count", "?")[:5]
|
||||
)
|
||||
|
||||
# Featured Offers grouped by rarity
|
||||
all_offers = base_offer_qs.order_by("created_at")
|
||||
featured = {}
|
||||
featured["All"] = all_offers[:5]
|
||||
grouped = defaultdict(list)
|
||||
for offer in all_offers:
|
||||
normalized_ids = set()
|
||||
for card in offer.have_cards.all():
|
||||
if card.rarity:
|
||||
normalized_ids.add(card.rarity.normalized_id)
|
||||
normalized_ids = {card.rarity.normalized_id for card in offer.have_cards.all() if card.rarity}
|
||||
for norm in normalized_ids:
|
||||
grouped[norm].append(offer)
|
||||
|
||||
# Map each normalized rarity id to a representative icon
|
||||
norm_ids_available = list(grouped.keys())
|
||||
rareness_qs = Rarity.objects.filter(pk__in=[6] + [nid for nid in norm_ids_available if nid != 6])
|
||||
rarity_map = {rarity.pk: rarity.icons for rarity in rareness_qs}
|
||||
|
||||
# Order groups by descending normalized rarity id
|
||||
for norm in sorted(grouped.keys(), reverse=True):
|
||||
offers = grouped[norm]
|
||||
icon_label = rarity_map.get(norm)
|
||||
if icon_label:
|
||||
featured[icon_label] = offers[:5]
|
||||
|
||||
context["featured_offers"] = featured
|
||||
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
# If the request is AJAX, return only the search results fragment
|
||||
context = self.get_context_data(**kwargs)
|
||||
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
|
||||
return TemplateResponse(request, "home/_search_results.html", context)
|
||||
return self.render_to_response(context)
|
||||
return context
|
||||
Loading…
Add table
Add a link
Reference in a new issue