feat: add user-scoped favorites and notes

This commit is contained in:
bisco
2026-04-07 18:11:19 +02:00
parent a5e1d841df
commit caa1f8354d
12 changed files with 364 additions and 93 deletions

View File

@ -3,7 +3,8 @@ from __future__ import annotations
from decimal import Decimal
from django.core.paginator import Paginator
from django.db.models import Count, Exists, OuterRef, Prefetch
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Exists, OuterRef, Prefetch, Q
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
@ -28,8 +29,11 @@ CONTEXT_SORTS = {
}
def apply_favorite_state(players):
favorite_ids = set(FavoritePlayer.objects.values_list("player_id", flat=True))
def apply_favorite_state(players, user):
if not user.is_authenticated:
favorite_ids = set()
else:
favorite_ids = set(FavoritePlayer.objects.filter(user=user).values_list("player_id", flat=True))
for player in players:
player.is_favorite = player.id in favorite_ids
@ -248,7 +252,7 @@ def player_list(request):
active_sort = sort_players(players, requested_sort, context_filters_used)
paginator = Paginator(players, PAGE_SIZE)
page_obj = paginator.get_page(request.GET.get("page"))
apply_favorite_state(page_obj.object_list)
apply_favorite_state(page_obj.object_list, request.user)
query_without_page = request.GET.copy()
query_without_page.pop("page", None)
@ -269,7 +273,7 @@ def player_list(request):
def player_detail(request, player_id: int):
player = get_object_or_404(
Player.objects.prefetch_related("roles", "specialties", "notes"),
Player.objects.prefetch_related("roles", "specialties"),
pk=player_id,
)
@ -278,7 +282,12 @@ def player_detail(request, player_id: int):
.select_related("season", "team", "competition", "stats")
.order_by("-season__start_year", "team__name", "competition__name")
)
notes = player.notes.all()
if request.user.is_authenticated:
notes = player.notes.filter(user=request.user)
is_favorite = FavoritePlayer.objects.filter(user=request.user, player=player).exists()
else:
notes = PlayerNote.objects.none()
is_favorite = False
return render(
request,
@ -287,46 +296,52 @@ def player_detail(request, player_id: int):
"player": player,
"contexts": contexts,
"notes": notes,
"is_favorite": FavoritePlayer.objects.filter(player=player).exists(),
"is_favorite": is_favorite,
},
)
@login_required
@require_POST
def add_favorite(request, player_id: int):
player = get_object_or_404(Player, pk=player_id)
FavoritePlayer.objects.get_or_create(player=player)
FavoritePlayer.objects.get_or_create(user=request.user, player=player)
return redirect_to_next(request, reverse("scouting:player_detail", args=[player.id]))
@login_required
@require_POST
def remove_favorite(request, player_id: int):
player = get_object_or_404(Player, pk=player_id)
FavoritePlayer.objects.filter(player=player).delete()
FavoritePlayer.objects.filter(user=request.user, player=player).delete()
return redirect_to_next(request, reverse("scouting:player_detail", args=[player.id]))
@login_required
@require_POST
def add_note(request, player_id: int):
player = get_object_or_404(Player, pk=player_id)
body = (request.POST.get("body") or "").strip()
if body:
PlayerNote.objects.create(player=player, body=body)
PlayerNote.objects.create(user=request.user, player=player, body=body)
return redirect_to_next(request, reverse("scouting:player_detail", args=[player.id]))
@login_required
@require_POST
def delete_note(request, player_id: int, note_id: int):
player = get_object_or_404(Player, pk=player_id)
PlayerNote.objects.filter(player=player, pk=note_id).delete()
PlayerNote.objects.filter(user=request.user, player=player, pk=note_id).delete()
return redirect_to_next(request, reverse("scouting:player_detail", args=[player.id]))
@login_required
def favorites_list(request):
favorites = list(
FavoritePlayer.objects.select_related("player")
FavoritePlayer.objects.filter(user=request.user)
.select_related("player")
.prefetch_related("player__roles", "player__specialties")
.annotate(note_count=Count("player__notes"))
.annotate(note_count=Count("player__notes", filter=Q(player__notes__user=request.user)))
.order_by("-created_at", "player__full_name")
)