From d93423088086c3166b5ab0e229dbe348723c2169 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Sep 2025 09:12:53 +0200 Subject: [PATCH 1/3] adds event_count for user in the dashboard --- tournaments/templates/admin/tournaments/dashboard.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tournaments/templates/admin/tournaments/dashboard.html b/tournaments/templates/admin/tournaments/dashboard.html index 3447820..d053c74 100644 --- a/tournaments/templates/admin/tournaments/dashboard.html +++ b/tournaments/templates/admin/tournaments/dashboard.html @@ -188,6 +188,7 @@ Date Joined Email Phone + Events @@ -209,6 +210,7 @@ {{ user.date_joined|date:"M d, Y H:i" }} {{ user.email }} {{ user.phone }} + {{ user.event_count }} {% empty %} From 8faf79fd943fcd833f00cad7bd22740476a5ecaf Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Sep 2025 14:47:03 +0200 Subject: [PATCH 2/3] adds claude.md --- CLAUDE.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c06eda1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,10 @@ +This is a django project that is used for padel tournaments management. +Here are the different apps: +- api: the api is used to communicate with the mobile app +- authentication: regroups authentications services +- biz: it's our CRM project to manage customers +- shop: the website that hosts the shop +- sync: the project used to synchronize the data between apps and the backend +- tournaments: the main website the display everything about the padel tournaments + +In production, the project runs with ASGI because we use websockets in the sync app. From 08f78e7de41eee7002899c19a85af94a9ca38254 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 16 Sep 2025 16:46:51 +0200 Subject: [PATCH 3/3] adds first draft for tournament summaries api --- api/serializers.py | 11 +++++++++++ api/urls.py | 1 + api/views.py | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/api/serializers.py b/api/serializers.py index 8efb24f..2611dfa 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -134,6 +134,17 @@ class TournamentSerializer(serializers.ModelSerializer): model = Tournament fields = '__all__' +class TournamentSummarySerializer(serializers.ModelSerializer): + + registration_count = serializers.SerializerMethodField() + + class Meta: + model = Tournament + fields = ['id', 'name', 'start_date', 'day_duration', 'team_count', 'federal_category', 'federal_level_category', 'federal_age_category', 'registration_count'] + + def get_registration_count(self, obj): + return len(obj.teams(True)) + class EventSerializer(serializers.ModelSerializer): class Meta: #club_id = serializers.PrimaryKeyRelatedField(queryset=Club.objects.all()) diff --git a/api/urls.py b/api/urls.py index 0f62dd1..38c8381 100644 --- a/api/urls.py +++ b/api/urls.py @@ -11,6 +11,7 @@ router.register(r'users', views.UserViewSet) router.register(r'user-agents', views.ShortUserViewSet) router.register(r'clubs', views.ClubViewSet) router.register(r'tournaments', views.TournamentViewSet) +router.register(r'tournament-summaries', views.TournamentSummaryViewSet) router.register(r'images', views.ImageViewSet) router.register(r'events', views.EventViewSet) router.register(r'rounds', views.RoundViewSet) diff --git a/api/views.py b/api/views.py index dea7aea..6f9a37a 100644 --- a/api/views.py +++ b/api/views.py @@ -12,7 +12,7 @@ from django.core.files.storage import default_storage from django.core.files.base import ContentFile from django.shortcuts import get_object_or_404 -from .serializers import ClubSerializer, CourtSerializer, DateIntervalSerializer, DrawLogSerializer, TournamentSerializer, UserSerializer, EventSerializer, RoundSerializer, GroupStageSerializer, MatchSerializer, TeamScoreSerializer, TeamRegistrationSerializer, PlayerRegistrationSerializer, PurchaseSerializer, ShortUserSerializer, FailedApiCallSerializer, LogSerializer, DeviceTokenSerializer, CustomUserSerializer, UnregisteredTeamSerializer, UnregisteredPlayerSerializer, ImageSerializer, ActivitySerializer, ProspectSerializer, EntitySerializer +from .serializers import ClubSerializer, CourtSerializer, DateIntervalSerializer, DrawLogSerializer, TournamentSerializer, UserSerializer, EventSerializer, RoundSerializer, GroupStageSerializer, MatchSerializer, TeamScoreSerializer, TeamRegistrationSerializer, PlayerRegistrationSerializer, PurchaseSerializer, ShortUserSerializer, FailedApiCallSerializer, LogSerializer, DeviceTokenSerializer, CustomUserSerializer, UnregisteredTeamSerializer, UnregisteredPlayerSerializer, ImageSerializer, ActivitySerializer, ProspectSerializer, EntitySerializer, TournamentSummarySerializer from tournaments.models import Club, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamScore, TeamRegistration, PlayerRegistration, Court, DateInterval, Purchase, FailedApiCall, Log, DeviceToken, DrawLog, UnregisteredTeam, UnregisteredPlayer, Image from biz.models import Activity, Prospect, Entity @@ -73,6 +73,19 @@ class ClubViewSet(SoftDeleteViewSet): def perform_create(self, serializer): serializer.save(creator=self.request.user) +class TournamentSummaryViewSet(SoftDeleteViewSet): + queryset = Tournament.objects.all() + serializer_class = TournamentSummarySerializer + + def get_queryset(self): + if self.request.user.is_anonymous: + return [] + + return self.queryset.filter( + Q(event__creator=self.request.user) | Q(related_user=self.request.user) + ).distinct() + + class TournamentViewSet(SoftDeleteViewSet): queryset = Tournament.objects.all() serializer_class = TournamentSerializer