Bonjour !
Je reviens avec un problème que je n’arrive pas à résoudre sans faire exploser le nombre de requêtes à ma BDD.
Voici le contexte : pour mon site (d’organisation de tournois), il y a un système de ronde suisse où à chaque ronde, on fait s’affronter des adversaires (représentés ici par des SideBySideSubscription
) appariés ensemble (les appariements étant représentés par des SideBySidePairing
).
Voici synthétiquement les deux modèles :
class SideBySideSubscription(models.Model):
team = models.ForeignKey("teams.Team", on_delete=models.CASCADE)
tournament = models.ForeignKey(SideBySideTournament, on_delete=models.CASCADE)
class SideBySidePairing(models.Model):
round_number = models.PositiveSmallIntegerField()
party_1 = models.ForeignKey(
SideBySideSubscription, on_delete=models.CASCADE, related_name="party_1"
)
party_2 = models.ForeignKey(
SideBySideSubscription,
on_delete=models.CASCADE,
related_name="party_2",
null=True,
blank=True,
)
tournament = models.ForeignKey(SideBySideTournament, on_delete=models.CASCADE)
Note : le champ party_2
peut être vide car le nombre de participants peut être impair.
A chaque ronde, je vérifie la validité de celle-ci pour éviter les erreurs humaines. Une des vérifications que je fais est d’être sûr que chaque SideBySideSubscription
n’est rattachée qu’à un et un seul SideBySidePairing
.
Pour ce faire, je parcours actuellement manuellement via une boucle :
for subscription in accepted_subscriptions:
pairings_for_round_ct = (
pairings.filter(party_1_id=subscription["id"]).count()
+ pairings.filter(party_2_id=subscription["id"]).count()
)
if pairings_for_round_ct > 1:
errors.append(
_("%(team_name)s is in more than one pairing")
% {"team_name": subscription["team__name"]}
)
if pairings_for_round_ct == 0:
errors.append(
_("%(team_name)s is not in the pairings")
% {"team_name": subscription["team__name"]}
)
Note encore : j’appelle les propriétés des objets via des dictionnaires car j’utilise .values()
plus haut.
C’est fonctionnel, mais très inefficace, et bien sûr ça grossit avec le nombre de SideBySideSubscription
, qui peut atteindre 600.
Du coup, j’aimerais trouver un moyen plus efficace de faire cela. Idéalement, en une requête, me renvoyer combien d’entités SideBySidePairing
sont liées à une SideBySideSubscription
donnée.
Malheureusement je ne vois pas du tout comment faire cela. Quelqu’un pourrait-il m’aider ?