Как эффективно рассчитать elo в django?
Я управляю ORM для обновления рейтинга ELO, но это трудно для меня.
Это таблица модели ELO. Если я вставлю данные между этими экземплярами, что произойдет?
id| league | match_date | player | rating
--+--------+------------+---------+--------
1| 1| 2022-01-01| AAA| 1015.0 (winner)
2| 1| 2022-01-01| BBB| 985.0 (loser)
3| 1| 2022-01-03| CCC| 1016.4 ...
4| 1| 2022-01-03| AAA| 999.4 ...
5| 2| 2022-01-05| AAA| 1015.0
6| 2| 2022-01-05| BBB| 985.0
7| 2| 2022-01-07| CCC| 1015.0
8| 2| 2022-01-07| BBB| 985.0
...
...
data to be inserted => (
league = 1,
match_date = 2022-01-02,
player = [AAA, CCC] (first is winner)
)
Упорядочение таблицы - league ASC, match_date ASC. Поэтому данные будут вставлены между второй и третьей строкой.
Однако, значения рейтинга после вставки данных не являются правильными. Я ищу, как обновить рейтинг эффективно ?
Запускать ли мне for loop для обновления всех рейтингов? По моему мнению, это создаст много хитов в DB.
Я уже создал ORM с помощью Subquery, но Subquery не вычисляет на основе вычисленных данных, а не данных из таблицы. Это устарело, потому что я вставил данные.
Кроме того, рейтинги различны для каждой лиги. Это означает, что у игрока есть рейтинг в каждой лиге.
Есть ли какой-нибудь метод с использованием ORM для решения этой проблемы, ответьте мне, пожалуйста.
UPDATE
# models.py
class Player(models.Model):
name = models.CharField(default="", max_length=30, unique=True)
class League(models.Model):
name = models.CharField(default="", max_length=30, unique=True)
k_factor = models.IntegerField(default=32)
is_elo_rating_active = models.BooleanField(default=False)
class Match(models.Model):
league = models.ForeignKey(
League, on_delete=models.CASCADE, related_name="matches")
date = models.DateField(default=timezone.now)
title = models.CharField(default="", max_length=100)
map = models.ForeignKey(
Map, on_delete=models.CASCADE, related_name="matches")
winner = models.ForeignKey(Player)
loser = models.ForeignKey(Player)
class Meta:
ordering = ["date", "league", "title"]
class Elo(models.Model):
Player = models.ForeignKey(Player, on_delete=models.CASCADE)
match = models.ForeignKey(Match, on_delete=models.CASCADE)
rating = models.DecimalField(default=1000.0, max_digits=6, decimal_places=1)
winning_state = models.BooleanField(default=False)
class Meta:
ordering = "match__date", "match__league", "match__title"