Skip to content

Commit

Permalink
lots of little performance improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
catgirlinspace committed Nov 12, 2024
1 parent a8288a8 commit bfe72ee
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 68 deletions.
21 changes: 21 additions & 0 deletions battles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions battles/templates/battles/view_battle.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

<h1 class="text-3xl font-splatoon1">
<a href="{% url 'profile' battle.uploader.username %}">{{ battle.uploader.display_name }}</a>'s battle on
<time datetime="{{ battle.played_time }}">{{ battle.played_time }}</time>
<time datetime="{{ battle.played_time.isoformat }}">{{ battle.played_time }}</time>

<button class="share-button inline-block"
data-url="https://splashcat.ink/battles/{{ battle.id }}/?share"
Expand Down Expand Up @@ -324,13 +324,13 @@ <h1 class="text-2xl font-splatoon1 pt-2">Related Battles</h1>
<a href="{% url 'battles:redirect_to_user_latest_battle' battle.uploader.username %}" data-direction="forwards"
class="battle-pagination-button py-2 px-4 rounded-full bg-gray-600">Latest Battle</a>
<div class="grow"></div>
{% with next_battle=battle.get_player_next_battle %}
{% with next_battle=battle.get_player_next_battle_minimal %}
<a href="{{ next_battle.get_absolute_url }}" data-direction="forwards"
class="battle-pagination-button py-2 px-4 rounded-full {% if next_battle %}bg-gray-600{% else %}bg-gray-600/50 text-gray-400{% endif %}">
Next
</a>
{% endwith %}
{% with previous_battle=battle.get_player_previous_battle %}
{% with previous_battle=battle.get_player_previous_battle_minimal %}
<a href="{{ previous_battle.get_absolute_url }}" data-direction="backwards"
class="battle-pagination-button py-2 px-4 rounded-full {% if previous_battle %}bg-gray-600{% else %}bg-gray-800 text-gray-400{% endif %}">
Previous
Expand Down
6 changes: 3 additions & 3 deletions battles/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
Expand Down Expand Up @@ -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,
})
Expand Down Expand Up @@ -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'),
})


Expand Down
2 changes: 1 addition & 1 deletion embed_images/templates/embed_images/user_splashtag.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{% include 'includes/splashtag.html' with splashtag=splashtag %}
</div>
<div class="absolute top-1 right-1 opacity-75 flex flex-row gap-4 items-end">
<div>{{ player.name }}#{{ player.name_id }}</div>
<div>{{ splashtag.name }}#{{ splashtag.name_id }}</div>
<div>@{{ profile_user.username }}</div>
<div>splashcat.ink</div>
</div>
Expand Down
9 changes: 2 additions & 7 deletions embed_images/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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,
})
2 changes: 1 addition & 1 deletion groups/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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', {
Expand Down
17 changes: 3 additions & 14 deletions splashcat/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions templates/includes/splashtag.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
<div class="absolute bottom-0 right-0 flex flex-row gap-2">
{% for badge in splashtag.badges %}
{% if badge is not None %}
<img src="{{ badge.image.url }}" class="h-8 w-8" alt="{{ badge.translated_description }}"
title="{{ badge.translated_description }}">
{% with translated_description=badge.translated_description %}
<img src="{{ badge.image.url }}" class="h-8 w-8" alt="{{ translated_description }}"
title="{{ translated_description }}">
{% endwith %}
{% else %}
<span class="h-8 w-8"></span>
{% endif %}
Expand Down
26 changes: 21 additions & 5 deletions users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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

Expand Down
49 changes: 26 additions & 23 deletions users/templates/users/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,33 @@
<div class="flex flex-col md:flex-row gap-4 overflow-x-clip">
<div class="basis-2/5 xl:basis-1/4 flex flex-col gap-2">
{% include 'users/profile_sidebar.html' with profile=profile_user %}

<button class="share-button inline w-fit"
data-url="https://splashcat.ink/@{{ profile_user.username }}/?share&cache={{ profile_user.battles.count }}"
data-content-type="Profile"
data-share-type="webShare"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-8 h-8 inline">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15"></path>
</svg>
</button>

<button class="share-button inline w-fit"
data-url="https://splashcat.ink/@{{ profile_user.username }}/?share&cache={{ profile_user.battles.count }}"
data-content-type="Profile"
data-share-type="clipboard"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 inline">
<path fill-rule="evenodd"
d="M19.902 4.098a3.75 3.75 0 00-5.304 0l-4.5 4.5a3.75 3.75 0 001.035 6.037.75.75 0 01-.646 1.353 5.25 5.25 0 01-1.449-8.45l4.5-4.5a5.25 5.25 0 117.424 7.424l-1.757 1.757a.75.75 0 11-1.06-1.06l1.757-1.757a3.75 3.75 0 000-5.304zm-7.389 4.267a.75.75 0 011-.353 5.25 5.25 0 011.449 8.45l-4.5 4.5a5.25 5.25 0 11-7.424-7.424l1.757-1.757a.75.75 0 111.06 1.06l-1.757 1.757a3.75 3.75 0 105.304 5.304l4.5-4.5a3.75 3.75 0 00-1.035-6.037.75.75 0 01-.354-1z"
clip-rule="evenodd"></path>
</svg>
</button>
{% with battle_count=profile_user.battles.count %}
<button class="share-button inline w-fit"
data-url="https://splashcat.ink/@{{ profile_user.username }}/?share&cache={{ battle_count }}"
data-content-type="Profile"
data-share-type="webShare"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-8 h-8 inline">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15"></path>
</svg>
</button>

<button class="share-button inline w-fit"
data-url="https://splashcat.ink/@{{ profile_user.username }}/?share&cache={{ battle_count }}"
data-content-type="Profile"
data-share-type="clipboard"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8 inline">
<path fill-rule="evenodd"
d="M19.902 4.098a3.75 3.75 0 00-5.304 0l-4.5 4.5a3.75 3.75 0 001.035 6.037.75.75 0 01-.646 1.353 5.25 5.25 0 01-1.449-8.45l4.5-4.5a5.25 5.25 0 117.424 7.424l-1.757 1.757a.75.75 0 11-1.06-1.06l1.757-1.757a3.75 3.75 0 000-5.304zm-7.389 4.267a.75.75 0 011-.353 5.25 5.25 0 011.449 8.45l-4.5 4.5a5.25 5.25 0 11-7.424-7.424l1.757-1.757a.75.75 0 111.06 1.06l-1.757 1.757a3.75 3.75 0 105.304 5.304l4.5-4.5a3.75 3.75 0 00-1.035-6.037.75.75 0 01-.354-1z"
clip-rule="evenodd"></path>
</svg>
</button>
{% endwith %}

{% with groups=profile_user.get_groups %}
{% if groups|length > 0 %}
<h2 class="text-xl font-splatoon1">Groups</h2>
Expand Down
11 changes: 3 additions & 8 deletions users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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,
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit bfe72ee

Please sign in to comment.