From a044302d55a434252ab7029813447640b4330ba1 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 4 Apr 2024 23:35:38 -0400 Subject: [PATCH] Revert "rework internal implementation of joining a contest solo." This reverts commit f0b93b96771094b84c6d8ce82b8b3aab636c4918. --- gameserver/models/contest.py | 20 ++++++++++------ gameserver/models/profile.py | 3 +-- gameserver/views/contest.py | 24 +++++++++++-------- templates/base.html | 2 +- templates/contest/detail.html | 3 ++- templates/contest/participation.html | 4 ++-- templates/contest/snippet/submission/row.html | 2 +- templates/contest/submission_list.html | 2 +- 8 files changed, 35 insertions(+), 25 deletions(-) diff --git a/gameserver/models/contest.py b/gameserver/models/contest.py index f25a9ce..c9f12d1 100644 --- a/gameserver/models/contest.py +++ b/gameserver/models/contest.py @@ -164,7 +164,7 @@ def is_visible_by(self, user): if not user.is_authenticated: return False - if self.organizations.exists() and self.organizations.filter(pk__in=user.organizations.all()).exists(): + if self.organizations.filter(pk__in=user.organizations.all()).exists(): return True return self.is_editable_by(user) @@ -176,7 +176,7 @@ def is_accessible_by(self, user): if not self.is_ongoing: return False - if self.organizations.exists() and self.organizations.filter(pk__in=user.organizations.all()).exists(): + if self.organizations.filter(pk__in=user.organizations.all()).exists(): return True if self.is_editable_by(user): @@ -241,19 +241,25 @@ def __init__(self, *args, **kwargs): "Team", on_delete=models.CASCADE, related_name="contest_participations", + null=True, blank=True, ) - @property - def name(self): - return self.team.name + participants = models.ManyToManyField("User", related_name="contest_participations", blank=True) def __str__(self): - return f"{self.name}'s Participation in {self.contest.name}" + return f"{self.participant}'s Participation in {self.contest.name}" def get_absolute_url(self): return reverse("contest_participation_detail", args=[self.pk]) + @cached_property + def participant(self): + if self.team is None: + return self.participants.first() + else: + return self.team + def _get_unique_correct_submissions(self): # Switch to ContestProblem -> Problem Later return ( @@ -400,7 +406,7 @@ class ContestSubmission(models.Model): ) def __str__(self): - return f"{self.participation.name}'s submission for {self.problem.problem.name} in {self.problem.contest.name}" + return f"{self.participation.participant}'s submission for {self.problem.problem.name} in {self.problem.contest.name}" @cached_property def is_correct(self): diff --git a/gameserver/models/profile.py b/gameserver/models/profile.py index 2d6dc7d..9b380ab 100644 --- a/gameserver/models/profile.py +++ b/gameserver/models/profile.py @@ -163,7 +163,7 @@ def has_firstblooded(self, problem): raise TypeError("problem must be a Problem or ContestProblem") def participation_for_contest(self, contest): - return ContestParticipation.objects.filter(team__members=self.id, contest=contest).first() + return ContestParticipation.objects.filter(participants=self, contest=contest).first() def remove_contest(self): self.current_contest = None @@ -181,7 +181,6 @@ def update_contest(self): update_contest.alters_data = True - class Organization(models.Model): owner = models.ForeignKey(User, on_delete=models.PROTECT, related_name="organizations_owning") admins = models.ManyToManyField("User", related_name="organizations_maintaining") diff --git a/gameserver/views/contest.py b/gameserver/views/contest.py index 9ef0206..adbb30b 100644 --- a/gameserver/views/contest.py +++ b/gameserver/views/contest.py @@ -77,7 +77,7 @@ def form_valid(self, form): team = form.cleaned_data["participant"] if ( - self.request.in_contest + self.request.user.in_contest and self.request.user.current_contest.contest == self.object ): contest_participation = models.ContestParticipation.objects.get_or_create( @@ -94,13 +94,17 @@ def form_valid(self, form): team=team, contest=self.object )[0] else: - new_team = models.Team.objects.create( - name=self.request.user.username, - owner=self.request.user, - ) - contest_participation = models.ContestParticipation.objects.get_or_create( - team=new_team, contest=self.object - )[0] + try: + contest_participation = models.ContestParticipation.objects.get( + team=None, + participants=self.request.user, + contest=self.object, + ) + except models.ContestParticipation.DoesNotExist: + contest_participation = models.ContestParticipation(contest=self.object) + contest_participation.save() + + contest_participation.participants.add(self.request.user) self.request.user.current_contest = contest_participation self.request.user.save() @@ -109,14 +113,14 @@ def form_valid(self, form): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - user: models.User = self.request.user + user = self.request.user if user.is_authenticated: if (data := cache.get(f"contest_{self.object.slug}_participant_count")) is None: context["user_accessible"] = self.object.is_accessible_by(user) context["user_participation"] = user.participation_for_contest(self.object) team_participant_count = user.teams.annotate( participant_count=Count( - "contest_participations__team", + "contest_participations__participants", filter=Q(contest_participations__contest=self.object), ) ).values_list("pk", "participant_count") diff --git a/templates/base.html b/templates/base.html index 3cbb336..b87a563 100644 --- a/templates/base.html +++ b/templates/base.html @@ -91,7 +91,7 @@

Loading countdown...

Currently participating in {{ request.participation.contest }} - as {{ request.participation.name }}. + as {{ request.participation.participant }}.

{% endif %} diff --git a/templates/contest/detail.html b/templates/contest/detail.html index 4c09d21..f267ed2 100644 --- a/templates/contest/detail.html +++ b/templates/contest/detail.html @@ -62,7 +62,7 @@
{{ contest.duration }} long
{% if request.user.current_contest.contest == contest %}

You are currently in this contest as {{ request.participation.team }}. + href="{{ request.participation.participant.get_absolute_url }}">{{ request.participation.participant }}.

{% else %}

@@ -108,6 +108,7 @@

{{ contest.duration }} long
{% bootstrap_field form.participant wrapper_class="mb-2" %}

+ Disabled for performance reasons

Once you participate as part of a team, you cannot change back to individual participation.

diff --git a/templates/contest/participation.html b/templates/contest/participation.html index 47a67a4..59e347c 100644 --- a/templates/contest/participation.html +++ b/templates/contest/participation.html @@ -6,13 +6,13 @@

{{ participation.team }}'s + href="{{ participation.participant.get_absolute_url }}">{{ participation.participant }}'s Participation in {{ participation.contest }}


- {% include "snippets/group_detail/members.html" with member_list=participation.team.members.all entity="participation" %} + {% include "snippets/group_detail/members.html" with member_list=participation.participants.all entity="participation" %}

Captured

diff --git a/templates/contest/snippet/submission/row.html b/templates/contest/snippet/submission/row.html index 9a67974..aa757e2 100644 --- a/templates/contest/snippet/submission/row.html +++ b/templates/contest/snippet/submission/row.html @@ -12,7 +12,7 @@ {% endif %} {% if not hide_participant %} - {{ contest_submission.participation.name }} + {{ contest_submission.participation.participant }} {% endif %} {% if not hide_timestamp %} diff --git a/templates/contest/submission_list.html b/templates/contest/submission_list.html index 5568f36..39ca2ae 100644 --- a/templates/contest/submission_list.html +++ b/templates/contest/submission_list.html @@ -3,7 +3,7 @@ {% block heading %} {% if contest_participation %} Submissions by - {{ contest_participation.name }} in + {{ contest_participation.participant }} in {{ contest }} {% else %} Submissions for {{ contest }}