diff --git a/battles/models.py b/battles/models.py index 3d84f5f8..c5cd0a71 100644 --- a/battles/models.py +++ b/battles/models.py @@ -84,6 +84,19 @@ def with_prefetch(self, include_player_gear=False): return self.select_related('uploader__github_link', 'vs_stage__name', 'vs_stage__image', 'splatfest') \ .prefetch_related('awards__name', 'battlevideo', 'teams').prefetch_related(player_prefetch) + def with_card_prefetch(self): + player_prefetch_queryset = Player.objects \ + .select_related('weapon__name', 'weapon__flat_image', 'weapon__sub__name', + 'weapon__sub__overlay_image', 'weapon__sub__mask_image', 'weapon__special__name', + 'weapon__special__overlay_image', 'weapon__special__mask_image').filter(is_self=True) + player_prefetch = Prefetch( + 'teams__players', + queryset=player_prefetch_queryset, + ) + + return self.prefetch_related('uploader__github_link', player_prefetch).select_related( + 'vs_stage__name', 'battlevideo', 'splatfest') + class Battle(models.Model): class VsMode(models.TextChoices): @@ -300,12 +313,20 @@ def get_player_next_battle(self): except Battle.DoesNotExist: return None + def get_player_next_battle_minimal(self): + return Battle.objects.only('id').filter(uploader_id=self.uploader_id, + played_time__gt=self.played_time).order_by("played_time").first() + def get_player_previous_battle(self): try: return self.get_previous_by_played_time(uploader_id=self.uploader_id) except Battle.DoesNotExist: return None + def get_player_previous_battle_minimal(self): + return Battle.objects.only('id').filter(uploader_id=self.uploader_id, played_time__lt=self.played_time).latest( + "played_time") + def find_related_battle_video(self): return self.uploader.battlevideo_set.filter( battle_start_time__gte=self.played_time - timedelta(minutes=1), diff --git a/battles/templates/battles/view_battle.html b/battles/templates/battles/view_battle.html index e5b95e4e..038708dc 100644 --- a/battles/templates/battles/view_battle.html +++ b/battles/templates/battles/view_battle.html @@ -34,7 +34,7 @@

{{ battle.uploader.display_name }}'s battle on - +

Latest Battle
- {% with next_battle=battle.get_player_next_battle %} + {% with next_battle=battle.get_player_next_battle_minimal %} Next {% endwith %} - {% with previous_battle=battle.get_player_previous_battle %} + {% with previous_battle=battle.get_player_previous_battle_minimal %} Previous diff --git a/battles/views.py b/battles/views.py index 82cdbb13..e85d6181 100644 --- a/battles/views.py +++ b/battles/views.py @@ -270,7 +270,7 @@ def check_if_battle_exists(request, splatnet_id): @login_required def get_latest_battles(request): - battles = request.user.battles.with_prefetch().order_by('-id')[:10] + battles = request.user.battles.with_card_prefetch().order_by('-id')[:10] return render(request, 'battles/htmx/latest_battles.html', { 'battles': battles, }) @@ -306,7 +306,7 @@ def create_battle_group(request): return redirect('battles:view_battle_group', new_group.id) - battles = Battle.objects.with_prefetch().filter(uploader=request.user).order_by('-id')[:50] + battles = Battle.objects.with_card_prefetch().filter(uploader=request.user).order_by('-id')[:50] return render(request, 'battles/groups/create.html', { 'battles': battles, }) @@ -340,7 +340,7 @@ def view_battle_group(request, group_id): 'win_count': win_count, 'lose_count': lose_count, 'win_rate': win_rate, - 'battles': battle_group.battles.with_prefetch().order_by('-played_time'), + 'battles': battle_group.battles.with_card_prefetch().order_by('-played_time'), }) diff --git a/embed_images/templates/embed_images/user_splashtag.html b/embed_images/templates/embed_images/user_splashtag.html index bef453f2..24523463 100644 --- a/embed_images/templates/embed_images/user_splashtag.html +++ b/embed_images/templates/embed_images/user_splashtag.html @@ -8,7 +8,7 @@ {% include 'includes/splashtag.html' with splashtag=splashtag %}
-
{{ player.name }}#{{ player.name_id }}
+
{{ splashtag.name }}#{{ splashtag.name_id }}
@{{ profile_user.username }}
splashcat.ink
diff --git a/embed_images/views.py b/embed_images/views.py index 1ec46e74..63f04592 100644 --- a/embed_images/views.py +++ b/embed_images/views.py @@ -36,8 +36,7 @@ def index(request): def user_stats(request, username): user = get_object_or_404(User, username__iexact=username) - latest_battle = user.battles.with_prefetch().latest('played_time') - splashtag = latest_battle.splashtag if latest_battle else None + splashtag = user.get_splashtag win_count = user.battles.filter(judgement='WIN').count() lose_count = user.battles.filter(judgement__in=['LOSE', 'DEEMED_LOSE']).count() @@ -81,13 +80,9 @@ def user_gear(request, username): def user_splashtag(request, username): user = get_object_or_404(User, username__iexact=username) - latest_battle = user.get_latest_battle() - player = latest_battle.player - splashtag = player.splashtag + splashtag = user.get_splashtag return render(request, "embed_images/user_splashtag.html", { 'profile_user': user, - 'latest_battle': latest_battle, - 'player': player, 'splashtag': splashtag, }) diff --git a/groups/views.py b/groups/views.py index 188a8606..4355052e 100644 --- a/groups/views.py +++ b/groups/views.py @@ -29,7 +29,7 @@ def groups_index(request): def view_group(request, group_id): group = get_object_or_404(Group, pk=group_id) group_all_members = list(group.members.all()) + [group.owner] - group_recent_battles = Battle.objects.with_prefetch().filter(uploader__in=group_all_members).order_by( + group_recent_battles = Battle.objects.with_card_prefetch().filter(uploader__in=group_all_members).order_by( "-played_time")[:16] is_group_member = request.user.is_authenticated and request.user in group_all_members diff --git a/search/views.py b/search/views.py index 702e3249..5610d73d 100644 --- a/search/views.py +++ b/search/views.py @@ -15,7 +15,7 @@ def search_for_players_played_with(request, npln_id: str): return HttpResponseBadRequest('You cannot search for yourself.') players = Player.objects.filter(team__battle__uploader_id=request.user.id, npln_id__iexact=npln_id).distinct() - battles_with_player = Battle.objects.with_prefetch().filter(teams__players__in=players).distinct().order_by( + battles_with_player = Battle.objects.with_card_prefetch().filter(teams__players__in=players).distinct().order_by( '-played_time') return render(request, 'search/search_for_players_played_with.html', { diff --git a/splashcat/views.py b/splashcat/views.py index 77c67128..afb441d7 100644 --- a/splashcat/views.py +++ b/splashcat/views.py @@ -10,20 +10,9 @@ def home(request): - player_prefetch_queryset = Player.objects \ - .select_related('weapon__name', 'weapon__flat_image', 'weapon__sub__name', - 'weapon__sub__overlay_image', 'weapon__sub__mask_image', 'weapon__special__name', - 'weapon__special__overlay_image', 'weapon__special__mask_image').filter(is_self=True) - player_prefetch = Prefetch( - 'teams__players', - queryset=player_prefetch_queryset, - ) - - recent_battles = Battle.objects.prefetch_related('uploader__github_link', player_prefetch).select_related( - 'vs_stage__name', 'battlevideo', 'splatfest').order_by('-uploaded_at')[:24] - user_recent_battles = request.user.battles.select_related('vs_stage__name', 'battlevideo', - 'splatfest').prefetch_related( - player_prefetch).order_by('-uploaded_at')[:12] if request.user.is_authenticated else None + recent_battles = Battle.objects.with_card_prefetch().order_by('-uploaded_at')[:24] + user_recent_battles = request.user.battles.with_card_prefetch().order_by('-uploaded_at')[ + :12] if request.user.is_authenticated else None return render(request, 'splashcat/home.html', { 'recent_battles': recent_battles, diff --git a/templates/includes/splashtag.html b/templates/includes/splashtag.html index 18e50975..ed73d48c 100644 --- a/templates/includes/splashtag.html +++ b/templates/includes/splashtag.html @@ -13,8 +13,10 @@
{% for badge in splashtag.badges %} {% if badge is not None %} - {{ badge.translated_description }} + {% with translated_description=badge.translated_description %} + {{ translated_description }} + {% endwith %} {% else %} {% endif %} diff --git a/users/models.py b/users/models.py index d3ab4ba3..aa824499 100644 --- a/users/models.py +++ b/users/models.py @@ -16,6 +16,7 @@ from django.core.files.base import ContentFile from django.core.validators import URLValidator from django.db import models +from django.db.models import Prefetch from django.template.loader import render_to_string from django.urls import reverse from django.utils.crypto import get_random_string @@ -24,7 +25,7 @@ import django.contrib.auth.models as django_auth_models -from battles.models import Battle +from battles.models import Battle, Player from splatnet_assets.common_model_choices import XBattleDivisions from splatnet_assets.fields import ColorField @@ -103,7 +104,7 @@ class User(AbstractUser): coral_friend_url = models.URLField(_("Nintendo Switch Online app friend URL"), blank=True, null=True, validators=[URLValidator( regex=r"^https:\/\/lounge\.nintendo\.com\/friendcode\/\d{4}-\d{4}-\d{4}\/[A-Za-z0-9]{10}$")]) - + def save(self, *args, **kwargs): for field_name in ['profile_picture', 'profile_cover', 'page_background']: image = getattr(self, field_name) @@ -116,7 +117,7 @@ def save(self, *args, **kwargs): img_no_exif.putdata(list(img.getdata())) buffer = io.BytesIO() - + output_format = 'JPEG' img_no_exif.save(buffer, format=output_format) buffer.seek(0) @@ -207,13 +208,28 @@ def get_latest_battle(self): @property def get_splashtag(self): try: - return self.battles.with_prefetch().latest('played_time').splashtag + player_prefetch_queryset = Player.objects \ + .select_related('title_adjective__string', 'title_subject__string', 'nameplate_background__image', + 'nameplate_badge_1__image', 'nameplate_badge_2__image', 'nameplate_badge_3__image', + 'nameplate_badge_1__description', 'nameplate_badge_2__description', + 'nameplate_badge_3__description').filter(is_self=True) + player_prefetch = Prefetch( + 'teams__players', + queryset=player_prefetch_queryset, + ) + return self.battles.prefetch_related(player_prefetch).latest('played_time').splashtag except Battle.DoesNotExist: return None def get_npln_id(self): try: - return self.battles.with_prefetch().latest('played_time').player.npln_id + player_prefetch_queryset = Player.objects \ + .only('npln_id').filter(is_self=True) + player_prefetch = Prefetch( + 'teams__players', + queryset=player_prefetch_queryset, + ) + return self.battles.prefetch_related(player_prefetch).latest('played_time').player.npln_id except Battle.DoesNotExist: return None diff --git a/users/templates/users/profile.html b/users/templates/users/profile.html index 13b55095..72576069 100644 --- a/users/templates/users/profile.html +++ b/users/templates/users/profile.html @@ -22,30 +22,33 @@
{% include 'users/profile_sidebar.html' with profile=profile_user %} - - - + {% with battle_count=profile_user.battles.count %} + + + + {% endwith %} + {% with groups=profile_user.get_groups %} {% if groups|length > 0 %}

Groups

diff --git a/users/views.py b/users/views.py index 9dddf038..a8c56dbe 100644 --- a/users/views.py +++ b/users/views.py @@ -29,8 +29,7 @@ def profile(request, username: str): user = get_object_or_404(User, username__iexact=username) - latest_battles = user.battles.with_prefetch().order_by('-played_time') \ - .select_related('vs_stage__name')[:18] + latest_battles = user.battles.with_card_prefetch().order_by('-played_time')[:18] splashtag = latest_battles[0].splashtag if latest_battles else None win_count = user.battles.filter(judgement='WIN').count() @@ -77,9 +76,7 @@ def profile(request, username: str): def profile_opengraph(request, username: str): user = get_object_or_404(User, username__iexact=username) - latest_battles = user.battles.with_prefetch().order_by('-played_time') \ - .select_related('vs_stage__name')[:12] - splashtag = latest_battles[0].splashtag if latest_battles else None + splashtag = user.get_splashtag win_count = user.battles.filter(judgement='WIN').count() lose_count = user.battles.filter(judgement__in=['LOSE', 'DEEMED_LOSE']).count() @@ -100,7 +97,6 @@ def profile_opengraph(request, username: str): { 'profile_user': user, 'splashtag': splashtag, - 'latest_battles': latest_battles, 'win_count': win_count, 'lose_count': lose_count, 'win_rate': win_rate, @@ -193,8 +189,7 @@ def profile_json(request, username: str): def profile_battle_list(request, username: str): user = get_object_or_404(User, username__iexact=username) - battles = user.battles.with_prefetch().order_by('-played_time') \ - .select_related('vs_stage__name') + battles = user.battles.with_card_prefetch().order_by('-played_time') paginator = Paginator(battles, 24)