1
1
import datetime
2
2
from typing import Any , List
3
3
4
- from django .db .models import F , OuterRef , Max
4
+ from django .db .models import F , OuterRef , Max , Subquery , Case , When , Value , BooleanField , TextField
5
5
from django .shortcuts import get_object_or_404
6
6
from ninja import NinjaAPI , Schema
7
7
8
8
from gameserver .models .cache import ContestScore
9
- from gameserver .models .contest import Contest , ContestProblem , ContestSubmission
9
+ from gameserver .models .profile import User
10
+ from gameserver .models .contest import Contest , ContestProblem , ContestSubmission , ContestParticipation
10
11
11
12
12
13
def unicode_safe (string ):
@@ -33,11 +34,12 @@ class CTFSchema(Schema):
33
34
lastAccept : Any = None
34
35
35
36
@staticmethod
36
- def resolve_lastAccept (obj ) -> int :
37
+ def resolve_lastAccept (obj : dict ) -> int :
37
38
"""Turns a datetime object into a timestamp."""
38
- if obj ["lastAccept" ] is None :
39
+ print (obj , ' - DEBUG PRINT' )
40
+ if obj ['lastAccept' ] is None :
39
41
return 0
40
- return int (obj [" lastAccept" ].timestamp ())
42
+ return int (obj [' lastAccept' ].timestamp ())
41
43
42
44
@staticmethod
43
45
def resolve_team (obj ):
@@ -61,20 +63,26 @@ def ctftime_standings(request, contest_name: str):
61
63
.order_by ("-submission__date_created" )
62
64
.values ("submission__date_created" )
63
65
)
66
+
64
67
standings = (
65
68
ContestScore .ranks (contest = contest_id )
66
69
.annotate (
67
70
pos = F ("rank" ),
68
71
score = F ("points" ),
69
- team = F ("participation__team__name" ),
72
+ is_solo = Case (
73
+ When (participation__team_id = None , then = Value (False )),
74
+ default = Value (True ),
75
+ output_field = BooleanField (),
76
+ ),
77
+ team = Case (
78
+ When (participation__team_id = None , then = Subquery ( # If the team is None, use the username of the participant ( solo player )
79
+ User .objects .filter (contest_participations = OuterRef ("participation_id" )).values (
80
+ "username" )[:1 ]
81
+ ),),
82
+ default = F ("participation__team__name" ),
83
+ output_field = TextField (),
84
+ ),
70
85
lastAccept = Max ("participation__submission__submission__date_created" ),
71
- # team=Coalesce(F("participation__team__name"), F("participation__participants__username")),
72
- # Using Coalesce and indexing
73
- # team=Case(
74
- # When(F("participation__team__isnull")==True, then=Q(("participation__participants")[0]["username"])),
75
- # default=F("team_name"),
76
- # output_field=TextField(),
77
- # ),
78
86
)
79
87
.values ("pos" , "score" , "team" , "lastAccept" )
80
88
)
0 commit comments