mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2024-12-25 06:22:22 +00:00
Reduce the usage of sync_to_async
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
4357d51b9a
commit
82cda0b279
@ -4,7 +4,6 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from random import randint, shuffle
|
from random import randint, shuffle
|
||||||
|
|
||||||
from asgiref.sync import sync_to_async
|
|
||||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
@ -31,7 +30,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
async def connect(self):
|
async def connect(self):
|
||||||
self.tournament_id = self.scope['url_route']['kwargs']['tournament_id']
|
self.tournament_id = self.scope['url_route']['kwargs']['tournament_id']
|
||||||
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
|
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
|
||||||
.prefetch_related('draw__current_round__current_pool__current_team').aget()
|
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
|
||||||
|
|
||||||
self.participations = []
|
self.participations = []
|
||||||
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team'):
|
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team'):
|
||||||
@ -68,7 +67,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
# Refresh tournament
|
# Refresh tournament
|
||||||
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
|
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
|
||||||
.prefetch_related('draw__current_round__current_pool__current_team').aget()
|
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
|
||||||
|
|
||||||
match content['type']:
|
match content['type']:
|
||||||
case 'set_language':
|
case 'set_language':
|
||||||
@ -155,7 +154,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
|
|
||||||
async def process_dice(self, trigram: str | None = None, **kwargs):
|
async def process_dice(self, trigram: str | None = None, **kwargs):
|
||||||
state = await sync_to_async(self.tournament.draw.get_state)()
|
state = self.tournament.draw.get_state()
|
||||||
|
|
||||||
if self.registration.is_volunteer:
|
if self.registration.is_volunteer:
|
||||||
if trigram:
|
if trigram:
|
||||||
@ -251,8 +250,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
tds_copy = tds.copy()
|
tds_copy = tds.copy()
|
||||||
round2 = await self.tournament.draw.round_set.filter(number=2).aget()
|
round2 = await self.tournament.draw.round_set.filter(number=2).aget()
|
||||||
round2_pools = await sync_to_async(lambda: list(Pool.objects.filter(
|
round2_pools = [p async for p in Pool.objects.filter(round__draw__tournament=self.tournament, round=round2)\
|
||||||
round__draw__tournament=self.tournament, round=round2).order_by('letter').all()))()
|
.order_by('letter').all()]
|
||||||
current_pool_id, current_passage_index = 0, 0
|
current_pool_id, current_passage_index = 0, 0
|
||||||
for i, td in enumerate(tds_copy):
|
for i, td in enumerate(tds_copy):
|
||||||
if i == len(tds) - 1 and round2_pools[0].size == 5:
|
if i == len(tds) - 1 and round2_pools[0].size == 5:
|
||||||
@ -273,9 +272,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
await self.tournament.draw.current_round.asave()
|
await self.tournament.draw.current_round.asave()
|
||||||
|
|
||||||
msg = "Les résultats des dés sont les suivants : "
|
msg = "Les résultats des dés sont les suivants : "
|
||||||
msg += await sync_to_async(lambda: ", ".join(
|
msg += ", ".join(f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})" for td in tds)
|
||||||
f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})"
|
|
||||||
for td in tds))()
|
|
||||||
msg += ". L'ordre de passage et les compositions des différentes poules sont affiché⋅es sur le côté. "
|
msg += ". L'ordre de passage et les compositions des différentes poules sont affiché⋅es sur le côté. "
|
||||||
msg += "Attention : les ordres de passage sont déterminés à partir des scores des dés, mais ne sont pas "
|
msg += "Attention : les ordres de passage sont déterminés à partir des scores des dés, mais ne sont pas "
|
||||||
msg += "directement l'ordre croissant des dés, afin d'avoir des poules mélangées."
|
msg += "directement l'ordre croissant des dés, afin d'avoir des poules mélangées."
|
||||||
@ -361,20 +358,20 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
||||||
{'type': 'draw.dice_visibility', 'visible': False})
|
{'type': 'draw.dice_visibility', 'visible': False})
|
||||||
|
|
||||||
trigram = await sync_to_async(lambda: pool.current_team.participation.team.trigram)()
|
trigram = pool.current_team.participation.team.trigram
|
||||||
await self.channel_layer.group_send(f"team-{trigram}",
|
await self.channel_layer.group_send(f"team-{trigram}",
|
||||||
{'type': 'draw.box_visibility', 'visible': True})
|
{'type': 'draw.box_visibility', 'visible': True})
|
||||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||||
{'type': 'draw.box_visibility', 'visible': True})
|
{'type': 'draw.box_visibility', 'visible': True})
|
||||||
|
|
||||||
async def select_problem(self, **kwargs):
|
async def select_problem(self, **kwargs):
|
||||||
state = await sync_to_async(self.tournament.draw.get_state)()
|
state = self.tournament.draw.get_state()
|
||||||
|
|
||||||
if state != 'WAITING_DRAW_PROBLEM':
|
if state != 'WAITING_DRAW_PROBLEM':
|
||||||
return await self.alert(_("This is not the time for this."), 'danger')
|
return await self.alert(_("This is not the time for this."), 'danger')
|
||||||
|
|
||||||
pool = await sync_to_async(lambda: self.tournament.draw.current_round.current_pool)()
|
pool = self.tournament.draw.current_round.current_pool
|
||||||
td = await sync_to_async(lambda: pool.current_team)()
|
td = pool.current_team
|
||||||
if not self.registration.is_volunteer:
|
if not self.registration.is_volunteer:
|
||||||
participation = await Participation.objects.filter(team__participants=self.registration)\
|
participation = await Participation.objects.filter(team__participants=self.registration)\
|
||||||
.prefetch_related('team').aget()
|
.prefetch_related('team').aget()
|
||||||
@ -394,7 +391,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
td.purposed = problem
|
td.purposed = problem
|
||||||
await td.asave()
|
await td.asave()
|
||||||
|
|
||||||
trigram = await sync_to_async(lambda: td.participation.team.trigram)()
|
trigram = td.participation.team.trigram
|
||||||
await self.channel_layer.group_send(f"team-{trigram}",
|
await self.channel_layer.group_send(f"team-{trigram}",
|
||||||
{'type': 'draw.box_visibility', 'visible': False})
|
{'type': 'draw.box_visibility', 'visible': False})
|
||||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||||
@ -412,14 +409,14 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
{'type': 'draw.set_info', 'draw': self.tournament.draw})
|
{'type': 'draw.set_info', 'draw': self.tournament.draw})
|
||||||
|
|
||||||
async def accept_problem(self, **kwargs):
|
async def accept_problem(self, **kwargs):
|
||||||
state = await sync_to_async(self.tournament.draw.get_state)()
|
state = self.tournament.draw.get_state()
|
||||||
|
|
||||||
if state != 'WAITING_CHOOSE_PROBLEM':
|
if state != 'WAITING_CHOOSE_PROBLEM':
|
||||||
return await self.alert(_("This is not the time for this."), 'danger')
|
return await self.alert(_("This is not the time for this."), 'danger')
|
||||||
|
|
||||||
r = await sync_to_async(lambda: self.tournament.draw.current_round)()
|
r = self.tournament.draw.current_round
|
||||||
pool = await sync_to_async(lambda: r.current_pool)()
|
pool = r.current_pool
|
||||||
td = await sync_to_async(lambda: pool.current_team)()
|
td = pool.current_team
|
||||||
if not self.registration.is_volunteer:
|
if not self.registration.is_volunteer:
|
||||||
participation = await Participation.objects.filter(team__participants=self.registration)\
|
participation = await Participation.objects.filter(team__participants=self.registration)\
|
||||||
.prefetch_related('team').aget()
|
.prefetch_related('team').aget()
|
||||||
@ -430,7 +427,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
td.purposed = None
|
td.purposed = None
|
||||||
await td.asave()
|
await td.asave()
|
||||||
|
|
||||||
trigram = await sync_to_async(lambda: td.participation.team.trigram)()
|
trigram = td.participation.team.trigram
|
||||||
msg = f"L'équipe <strong>{trigram}</strong> a accepté le problème <strong>{td.accepted} : " \
|
msg = f"L'équipe <strong>{trigram}</strong> a accepté le problème <strong>{td.accepted} : " \
|
||||||
f"{settings.PROBLEMS[td.accepted - 1]}</strong>. "
|
f"{settings.PROBLEMS[td.accepted - 1]}</strong>. "
|
||||||
if pool.size == 5 and await pool.teamdraw_set.filter(accepted=td.accepted).acount() < 2:
|
if pool.size == 5 and await pool.teamdraw_set.filter(accepted=td.accepted).acount() < 2:
|
||||||
@ -456,7 +453,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
pool.current_team = next_td
|
pool.current_team = next_td
|
||||||
await pool.asave()
|
await pool.asave()
|
||||||
|
|
||||||
new_trigram = await sync_to_async(lambda: next_td.participation.team.trigram)()
|
new_trigram = next_td.participation.team.trigram
|
||||||
await self.channel_layer.group_send(f"team-{new_trigram}",
|
await self.channel_layer.group_send(f"team-{new_trigram}",
|
||||||
{'type': 'draw.box_visibility', 'visible': True})
|
{'type': 'draw.box_visibility', 'visible': True})
|
||||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||||
@ -554,14 +551,14 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
{'type': 'draw.set_active', 'draw': self.tournament.draw})
|
{'type': 'draw.set_active', 'draw': self.tournament.draw})
|
||||||
|
|
||||||
async def reject_problem(self, **kwargs):
|
async def reject_problem(self, **kwargs):
|
||||||
state = await sync_to_async(self.tournament.draw.get_state)()
|
state = self.tournament.draw.get_state()
|
||||||
|
|
||||||
if state != 'WAITING_CHOOSE_PROBLEM':
|
if state != 'WAITING_CHOOSE_PROBLEM':
|
||||||
return await self.alert(_("This is not the time for this."), 'danger')
|
return await self.alert(_("This is not the time for this."), 'danger')
|
||||||
|
|
||||||
r = await sync_to_async(lambda: self.tournament.draw.current_round)()
|
r = self.tournament.draw.current_round
|
||||||
pool = await sync_to_async(lambda: r.current_pool)()
|
pool = r.current_pool
|
||||||
td = await sync_to_async(lambda: pool.current_team)()
|
td = pool.current_team
|
||||||
if not self.registration.is_volunteer:
|
if not self.registration.is_volunteer:
|
||||||
participation = await Participation.objects.filter(team__participants=self.registration)\
|
participation = await Participation.objects.filter(team__participants=self.registration)\
|
||||||
.prefetch_related('team').aget()
|
.prefetch_related('team').aget()
|
||||||
@ -577,7 +574,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
remaining = len(settings.PROBLEMS) - 5 - len(td.rejected)
|
remaining = len(settings.PROBLEMS) - 5 - len(td.rejected)
|
||||||
|
|
||||||
trigram = await sync_to_async(lambda: td.participation.team.trigram)()
|
trigram = td.participation.team.trigram
|
||||||
msg = f"L'équipe <strong>{trigram}</strong> a refusé le problème <strong>{problem} : " \
|
msg = f"L'équipe <strong>{trigram}</strong> a refusé le problème <strong>{problem} : " \
|
||||||
f"{settings.PROBLEMS[problem - 1]}</strong>. "
|
f"{settings.PROBLEMS[problem - 1]}</strong>. "
|
||||||
if remaining >= 0:
|
if remaining >= 0:
|
||||||
@ -606,7 +603,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
pool.current_team = next_td
|
pool.current_team = next_td
|
||||||
await pool.asave()
|
await pool.asave()
|
||||||
|
|
||||||
new_trigram = await sync_to_async(lambda: next_td.participation.team.trigram)()
|
new_trigram = next_td.participation.team.trigram
|
||||||
await self.channel_layer.group_send(f"team-{new_trigram}",
|
await self.channel_layer.group_send(f"team-{new_trigram}",
|
||||||
{'type': 'draw.box_visibility', 'visible': True})
|
{'type': 'draw.box_visibility', 'visible': True})
|
||||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||||
@ -621,8 +618,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
async def export(self, **kwargs):
|
async def export(self, **kwargs):
|
||||||
async for r in self.tournament.draw.round_set.all():
|
async for r in self.tournament.draw.round_set.all():
|
||||||
async for pool in r.pool_set.all():
|
async for pool in r.pool_set.all():
|
||||||
if await sync_to_async(lambda: pool.exportable)():
|
if await pool.is_exportable():
|
||||||
await sync_to_async(pool.export)()
|
await pool.export()
|
||||||
|
|
||||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||||
{'type': 'draw.export_visibility', 'visible': False})
|
{'type': 'draw.export_visibility', 'visible': False})
|
||||||
@ -645,10 +642,10 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
notes = dict()
|
notes = dict()
|
||||||
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team').all():
|
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team').all():
|
||||||
notes[participation] = sum([await sync_to_async(pool.average)(participation)
|
notes[participation] = sum([await pool.aaverage(participation)
|
||||||
async for pool in self.tournament.pools.filter(participations=participation)
|
async for pool in self.tournament.pools.filter(participations=participation)\
|
||||||
|
.prefetch_related('passages').prefetch_related('tweaks')
|
||||||
if pool.results_available])
|
if pool.results_available])
|
||||||
print(participation.team.trigram, notes[participation])
|
|
||||||
ordered_participations = sorted(notes.keys(), key=lambda x: -notes[x])
|
ordered_participations = sorted(notes.keys(), key=lambda x: -notes[x])
|
||||||
async for pool in r2.pool_set.order_by('letter').all():
|
async for pool in r2.pool_set.order_by('letter').all():
|
||||||
for i in range(pool.size):
|
for i in range(pool.size):
|
||||||
@ -711,14 +708,13 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
|
|
||||||
async def draw_set_active(self, content):
|
async def draw_set_active(self, content):
|
||||||
r = content['draw'].current_round
|
r = content['draw'].current_round
|
||||||
await self.send_json(
|
await self.send_json({
|
||||||
await sync_to_async(lambda: {
|
'type': 'set_active',
|
||||||
'type': 'set_active',
|
'round': r.number,
|
||||||
'round': r.number,
|
'poule': r.current_pool.get_letter_display() if r.current_pool else None,
|
||||||
'poule': r.current_pool.get_letter_display() if r.current_pool else None,
|
'team': r.current_pool.current_team.participation.team.trigram \
|
||||||
'team': r.current_pool.current_team.participation.team.trigram \
|
if r.current_pool and r.current_pool.current_team else None,
|
||||||
if r.current_pool and r.current_pool.current_team else None,
|
})
|
||||||
})())
|
|
||||||
|
|
||||||
async def draw_set_problem(self, content):
|
async def draw_set_problem(self, content):
|
||||||
await self.send_json({'type': 'set_problem', 'round': content['round'],
|
await self.send_json({'type': 'set_problem', 'round': content['round'],
|
||||||
|
135
draw/models.py
135
draw/models.py
@ -37,10 +37,36 @@ class Draw(models.Model):
|
|||||||
return reverse_lazy('draw:index') + f'#{slugify(self.tournament.name)}'
|
return reverse_lazy('draw:index') + f'#{slugify(self.tournament.name)}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exportable(self):
|
def exportable(self) -> bool:
|
||||||
|
"""
|
||||||
|
True if any pool of the draw is exportable, ie. can be exported to the tournament interface.
|
||||||
|
|
||||||
|
This operation is synchronous.
|
||||||
|
"""
|
||||||
return any(pool.exportable for r in self.round_set.all() for pool in r.pool_set.all())
|
return any(pool.exportable for r in self.round_set.all() for pool in r.pool_set.all())
|
||||||
|
|
||||||
def get_state(self):
|
async def is_exportable(self) -> bool:
|
||||||
|
"""
|
||||||
|
True if any pool of the draw is exportable, ie. can be exported to the tournament interface.
|
||||||
|
|
||||||
|
This operation is asynchronous.
|
||||||
|
"""
|
||||||
|
return any([await pool.is_exportable() async for r in self.round_set.all() async for pool in r.pool_set.all()])
|
||||||
|
|
||||||
|
def get_state(self) -> str:
|
||||||
|
"""
|
||||||
|
The current state of the draw.
|
||||||
|
Can be:
|
||||||
|
|
||||||
|
* **DICE_SELECT_POULES** if we are waiting for teams to launch their dice to determine pools and passage order ;
|
||||||
|
* **DICE_ORDER_POULE** if we are waiting for teams to launch their dice to determine the problem draw order ;
|
||||||
|
* **WAITING_DRAW_PROBLEM** if we are waiting for a team to draw a problem ;
|
||||||
|
* **WAITING_CHOOSE_PROBLEM** if we are waiting for a team to accept or reject a problem ;
|
||||||
|
* **WAITING_FINAL** if this is the final tournament and we are between the two rounds ;
|
||||||
|
* **DRAW_ENDED** if the draw is ended.
|
||||||
|
|
||||||
|
Warning: the current round and the current team must be prefetched in an async context.
|
||||||
|
"""
|
||||||
if self.current_round.current_pool is None:
|
if self.current_round.current_pool is None:
|
||||||
return 'DICE_SELECT_POULES'
|
return 'DICE_SELECT_POULES'
|
||||||
elif self.current_round.current_pool.current_team is None:
|
elif self.current_round.current_pool.current_team is None:
|
||||||
@ -151,7 +177,7 @@ class Round(models.Model):
|
|||||||
return self.teamdraw_set.order_by('pool__letter', 'passage_index').all()
|
return self.teamdraw_set.order_by('pool__letter', 'passage_index').all()
|
||||||
|
|
||||||
async def next_pool(self):
|
async def next_pool(self):
|
||||||
pool = await sync_to_async(lambda: self.current_pool)()
|
pool = self.current_pool
|
||||||
return await self.pool_set.aget(letter=pool.letter + 1)
|
return await self.pool_set.aget(letter=pool.letter + 1)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -207,70 +233,75 @@ class Pool(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def trigrams(self):
|
def trigrams(self):
|
||||||
return [td.participation.team.trigram for td in self.teamdraw_set.order_by('passage_index').all()]
|
return [td.participation.team.trigram for td in self.teamdraw_set.order_by('passage_index')\
|
||||||
|
.prefetch_related('participation__team').all()]
|
||||||
|
|
||||||
async def atrigrams(self):
|
async def atrigrams(self):
|
||||||
return await sync_to_async(lambda: self.trigrams)()
|
return [td.participation.team.trigram async for td in self.teamdraw_set.order_by('passage_index')\
|
||||||
|
.prefetch_related('participation__team').all()]
|
||||||
|
|
||||||
async def next_td(self):
|
async def next_td(self):
|
||||||
td = await sync_to_async(lambda: self.current_team)()
|
td = self.current_team
|
||||||
current_index = (td.choose_index + 1) % self.size
|
current_index = (td.choose_index + 1) % self.size
|
||||||
td = await self.teamdraw_set.aget(choose_index=current_index)
|
td = await self.teamdraw_set.prefetch_related('participation__team').aget(choose_index=current_index)
|
||||||
while td.accepted:
|
while td.accepted:
|
||||||
current_index += 1
|
current_index += 1
|
||||||
current_index %= self.size
|
current_index %= self.size
|
||||||
td = await self.teamdraw_set.aget(choose_index=current_index)
|
td = await self.teamdraw_set.prefetch_related('participation__team').aget(choose_index=current_index)
|
||||||
return td
|
return td
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exportable(self):
|
def exportable(self):
|
||||||
return self.associated_pool is None and self.teamdraw_set.exists() \
|
return self.associated_pool_id is None and self.teamdraw_set.exists() \
|
||||||
and all(td.accepted is not None for td in self.teamdraw_set.all())
|
and all(td.accepted is not None for td in self.teamdraw_set.all())
|
||||||
|
|
||||||
def export(self):
|
async def is_exportable(self):
|
||||||
from django.db import transaction
|
return self.associated_pool_id is None and await self.teamdraw_set.aexists() \
|
||||||
with transaction.atomic():
|
and all([td.accepted is not None async for td in self.teamdraw_set.all()])
|
||||||
self.associated_pool = PPool.objects.create(
|
|
||||||
tournament=self.round.draw.tournament,
|
async def export(self):
|
||||||
round=self.round.number,
|
self.associated_pool = await PPool.objects.acreate(
|
||||||
letter=self.letter,
|
tournament=self.round.draw.tournament,
|
||||||
|
round=self.round.number,
|
||||||
|
letter=self.letter,
|
||||||
|
)
|
||||||
|
await self.associated_pool.juries.aset(self.round.draw.tournament.organizers.all())
|
||||||
|
tds = [td async for td in self.team_draws.prefetch_related('participation')]
|
||||||
|
await self.associated_pool.participations.aset([td.participation async for td in self.team_draws\
|
||||||
|
.prefetch_related('participation')])
|
||||||
|
await self.asave()
|
||||||
|
|
||||||
|
if len(tds) == 3:
|
||||||
|
table = [
|
||||||
|
[0, 1, 2],
|
||||||
|
[1, 2, 0],
|
||||||
|
[2, 0, 1],
|
||||||
|
]
|
||||||
|
elif len(tds) == 4:
|
||||||
|
table = [
|
||||||
|
[0, 1, 2],
|
||||||
|
[1, 2, 3],
|
||||||
|
[2, 3, 0],
|
||||||
|
[3, 0, 1],
|
||||||
|
]
|
||||||
|
elif len(tds) == 5:
|
||||||
|
table = [
|
||||||
|
[0, 2, 3],
|
||||||
|
[1, 3, 4],
|
||||||
|
[2, 0, 1],
|
||||||
|
[3, 4, 0],
|
||||||
|
[4, 1, 2],
|
||||||
|
]
|
||||||
|
|
||||||
|
for line in table:
|
||||||
|
await Passage.objects.acreate(
|
||||||
|
pool=self.associated_pool,
|
||||||
|
solution_number=tds[line[0]].accepted,
|
||||||
|
defender=tds[line[0]].participation,
|
||||||
|
opponent=tds[line[1]].participation,
|
||||||
|
reporter=tds[line[2]].participation,
|
||||||
|
defender_penalties=tds[line[0]].penalty_int,
|
||||||
)
|
)
|
||||||
self.associated_pool.juries.set(self.round.draw.tournament.organizers.all())
|
|
||||||
tds = list(self.team_draws)
|
|
||||||
self.associated_pool.participations.set([td.participation for td in tds])
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
if len(tds) == 3:
|
|
||||||
table = [
|
|
||||||
[0, 1, 2],
|
|
||||||
[1, 2, 0],
|
|
||||||
[2, 0, 1],
|
|
||||||
]
|
|
||||||
elif len(tds) == 4:
|
|
||||||
table = [
|
|
||||||
[0, 1, 2],
|
|
||||||
[1, 2, 3],
|
|
||||||
[2, 3, 0],
|
|
||||||
[3, 0, 1],
|
|
||||||
]
|
|
||||||
elif len(tds) == 5:
|
|
||||||
table = [
|
|
||||||
[0, 2, 3],
|
|
||||||
[1, 3, 4],
|
|
||||||
[2, 0, 1],
|
|
||||||
[3, 4, 0],
|
|
||||||
[4, 1, 2],
|
|
||||||
]
|
|
||||||
|
|
||||||
for line in table:
|
|
||||||
Passage.objects.create(
|
|
||||||
pool=self.associated_pool,
|
|
||||||
solution_number=tds[line[0]].accepted,
|
|
||||||
defender=tds[line[0]].participation,
|
|
||||||
opponent=tds[line[1]].participation,
|
|
||||||
reporter=tds[line[2]].participation,
|
|
||||||
defender_penalties=tds[line[0]].penalty_int,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(format_lazy(_("Pool {letter}{number}"), letter=self.get_letter_display(), number=self.round.number))
|
return str(format_lazy(_("Pool {letter}{number}"), letter=self.get_letter_display(), number=self.round.number))
|
||||||
|
@ -405,6 +405,10 @@ class Pool(models.Model):
|
|||||||
return sum(passage.average(participation) for passage in self.passages.all()) \
|
return sum(passage.average(participation) for passage in self.passages.all()) \
|
||||||
+ sum(tweak.diff for tweak in participation.tweaks.filter(pool=self).all())
|
+ sum(tweak.diff for tweak in participation.tweaks.filter(pool=self).all())
|
||||||
|
|
||||||
|
async def aaverage(self, participation):
|
||||||
|
return sum([passage.average(participation) async for passage in self.passages.all()]) \
|
||||||
|
+ sum([tweak.diff async for tweak in participation.tweaks.filter(pool=self).all()])
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("participation:pool_detail", args=(self.pk,))
|
return reverse_lazy("participation:pool_detail", args=(self.pk,))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user