from django.db import models from django.db.models import F from django.db.models.expressions import Window from django.db.models.functions import Rank class Version(models.Model): name = models.CharField(max_length=50, unique=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self) -> str: return self.name class ScoreManager(models.Manager): def get_queryset(self) -> models.QuerySet["Score"]: return ( super() .get_queryset() .select_related("version") .annotate( rank=Window( expression=Rank(), order_by=F("points").desc(), ) ) ) class Score(models.Model): username = models.CharField(max_length=100) points = models.IntegerField() version = models.ForeignKey( Version, on_delete=models.PROTECT, null=True, blank=True, related_name="scores" ) created_at = models.DateTimeField(auto_now_add=True) objects = ScoreManager() class Meta: ordering = ["-points"] def __str__(self) -> str: return f"{self.username}: {self.points}"