diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py index db8f4b6..5add355 100644 --- a/accounts/migrations/0001_initial.py +++ b/accounts/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.2 on 2025-03-16 04:58 +# Generated by Django 5.1.2 on 2025-03-16 18:18 import django.contrib.auth.models import django.contrib.auth.validators diff --git a/cards/migrations/0001_initial.py b/cards/migrations/0001_initial.py index b13630e..52471c3 100644 --- a/cards/migrations/0001_initial.py +++ b/cards/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.2 on 2025-03-16 04:58 +# Generated by Django 5.1.2 on 2025-03-16 18:18 import django.db.models.deletion from django.db import migrations, models diff --git a/cards/templatetags/card_badge.py b/cards/templatetags/card_badge.py index 1dc125b..9842704 100644 --- a/cards/templatetags/card_badge.py +++ b/cards/templatetags/card_badge.py @@ -6,11 +6,13 @@ register = template.Library() @register.inclusion_tag("templatetags/card_badge.html") def card_badge(card, quantity=1): + # Freeze the decks queryset once so that both the iteration and count use the same data + decks = list(card.decks.all()) if card else [] return { 'card': card, 'quantity': quantity, - 'decks': card.decks.all() if card else None, - 'num_decks': card.decks.count() if card else None, + 'decks': decks, + 'num_decks': len(decks), } @register.filter @@ -21,7 +23,7 @@ def card_badge_inline(card, quantity=1): html = render_to_string("templatetags/card_badge.html", { 'card': card, 'quantity': quantity, - 'decks': card.decks.all() if card else None, - 'num_decks': card.decks.count() if card else None, + 'decks': list(card.decks.all()) if card else [], + 'num_decks': len(list(card.decks.all())) if card else 0, }) return mark_safe(html) \ No newline at end of file diff --git a/django_project/settings.py b/django_project/settings.py index 81fdf59..46e34fe 100644 --- a/django_project/settings.py +++ b/django_project/settings.py @@ -47,7 +47,7 @@ INSTALLED_APPS = [ 'allauth.socialaccount.providers.google', "crispy_forms", "crispy_tailwind", - "debug_toolbar", + #"debug_toolbar", "el_pagination", "tailwind", "theme", @@ -56,8 +56,15 @@ INSTALLED_APPS = [ "cards", "home", "trades.apps.TradesConfig", + "silk", ] +SILKY_PYTHON_PROFILER = True +SILKY_AUTHENTICATION = True +SILKY_AUTHORISATION = True +SILKY_PERMISSIONS = lambda user: user.is_superuser +SILKY_META = True + TAILWIND_APP_NAME = 'theme' # https://docs.djangoproject.com/en/dev/ref/settings/#middleware @@ -66,12 +73,13 @@ MIDDLEWARE = [ "whitenoise.middleware.WhiteNoiseMiddleware", # WhiteNoise "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", - "debug_toolbar.middleware.DebugToolbarMiddleware", # Django Debug Toolbar + #"debug_toolbar.middleware.DebugToolbarMiddleware", # Django Debug Toolbar "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "allauth.account.middleware.AccountMiddleware", # django-allauth + 'silk.middleware.SilkyMiddleware', "django_browser_reload.middleware.BrowserReloadMiddleware", #"django_project.middleware.AutoLoginMiddleware", ] @@ -291,6 +299,6 @@ else: CACHES = { "default": { "BACKEND": "django.core.cache.backends.db.DatabaseCache", - "LOCATION": "site_cache", + "LOCATION": "django_site_cache", } } \ No newline at end of file diff --git a/django_project/urls.py b/django_project/urls.py index 505ad30..c159e94 100644 --- a/django_project/urls.py +++ b/django_project/urls.py @@ -10,6 +10,7 @@ urlpatterns = [ path('account/', include('accounts.urls')), path("trades/", include("trades.urls")), path("__reload__/", include("django_browser_reload.urls")), + path('silk/', include('silk.urls', namespace='silk')), ] if settings.DEBUG: diff --git a/home/views.py b/home/views.py index 176ed9f..a728f5d 100644 --- a/home/views.py +++ b/home/views.py @@ -9,10 +9,12 @@ 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 +from silk.profiling.profiler import silk_profile class HomePageView(TemplateView): template_name = "home/home.html" + @silk_profile(name='Home Page') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -29,37 +31,40 @@ class HomePageView(TemplateView): context["most_offered_cards"] = ( Card.objects_no_prefetch.filter(tradeofferhavecard__isnull=False) .annotate(offer_count=Sum("tradeofferhavecard__quantity")) - .order_by("-offer_count", "?")[:6] + .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] + .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] + .order_by("offer_count")[:6] ) featured = {} + # Featured "All" offers featured["All"] = base_offer_qs.order_by("created_at")[:6] + # Get the normalized ids for rarities with pk<=5. 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)} + 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 each normalized id (sorted descending), filter base offers that have the matching trade offer 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 + rarity__normalized_id=norm # now using trade_offer.rarity ).order_by("created_at").distinct()[:6] icon_label = rarity_map.get(norm) if icon_label: diff --git a/requirements.txt b/requirements.txt index 0781862..759a4bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,7 @@ django-daisy==1.0.13 django-debug-toolbar==4.4.6 django-el-pagination==4.1.2 django-environ==0.12.0 +django-silk==5.3.1 django-tailwind-4[reload]==0.1.4 django-widget-tweaks==1.5.0 gunicorn==23.0.0 diff --git a/theme/templates/base.html b/theme/templates/base.html index a2a5fc3..68b1a9c 100644 --- a/theme/templates/base.html +++ b/theme/templates/base.html @@ -53,7 +53,7 @@ class="menu menu-sm dropdown-content bg-base-100 rounded-box z-1 mt-3 w-52 p-2 shadow">
  • Home
  • - Trade + Trades