Add admin menu

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-04-03 18:10:52 +02:00
parent bd31375bf3
commit 073d761a03
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
5 changed files with 211 additions and 53 deletions

View File

@ -1,2 +1,62 @@
# Copyright (C) 2023 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .models import Draw, Round, Pool, TeamDraw
@admin.register(Draw)
class DrawAdmin(admin.ModelAdmin):
list_display = ('tournament', 'teams', 'current_round', 'get_state',)
list_filter = ('tournament', 'current_round',)
search_fields = ('tournament__name', 'tournament__participation__team__trigram',)
@admin.display(description=_("teams"))
def teams(self, record: Draw):
return ', '.join(p.team.trigram for p in record.tournament.participations.filter(valid=True).all())
@admin.register(Round)
class RoundAdmin(admin.ModelAdmin):
list_display = ('draw', 'number', 'teams',)
list_filter = ('draw__tournament', 'number',)
search_fields = ('draw__tournament__name', 'pool__teamdraw__participation__team__trigram')
ordering = ('draw__tournament__name', 'number')
@admin.display(description=_("teams"))
def teams(self, record: Round):
return ', '.join(td.participation.team.trigram for td in record.team_draws)
@admin.register(Pool)
class PoolAdmin(admin.ModelAdmin):
list_display = ('tournament', 'round', 'letter', 'teams')
list_filter = ('round__draw__tournament', 'round__number', 'letter')
ordering = ('round__draw__tournament__name', 'round', 'letter')
search_fields = ('round__draw__tournament__name', 'teamdraw__participation__team__trigram',)
@admin.display(ordering='round__draw__tournament__name', description=_("tournament"))
def tournament(self, record):
return record.round.draw.tournament
@admin.display(description=_("teams"))
def teams(self, record: Round):
return ', '.join(td.participation.team.trigram for td in record.team_draws)
@admin.register(TeamDraw)
class TeamDrawAdmin(admin.ModelAdmin):
list_display = ('participation', 'tournament', 'view_round', 'pool', 'accepted', 'rejected',
'passage_index', 'choose_index', 'passage_dice', 'choice_dice',)
list_filter = ('round__draw__tournament', 'round__number', 'pool__letter',)
search_fields = ('round__draw__tournament__name', 'participation__team__trigram',)
@admin.display(ordering='round__draw__tournament__name', description=_("tournament"))
def tournament(self, record):
return record.round.draw.tournament
@admin.display(ordering='round__number', description=_('round'))
def view_round(self, record):
return record.round.get_number_display()

View File

@ -0,0 +1,65 @@
# Generated by Django 4.1.7 on 2023-04-03 16:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("draw", "0008_alter_pool_letter"),
]
operations = [
migrations.AlterModelOptions(
name="pool",
options={
"ordering": (
"round__draw__tournament__name",
"round__number",
"letter",
),
"verbose_name": "pool",
"verbose_name_plural": "pools",
},
),
migrations.AlterModelOptions(
name="round",
options={
"ordering": ("draw__tournament__name", "number"),
"verbose_name": "round",
"verbose_name_plural": "rounds",
},
),
migrations.AlterModelOptions(
name="teamdraw",
options={
"ordering": (
"round__draw__tournament__name",
"round__number",
"pool__letter",
"passage_index",
),
"verbose_name": "team draw",
"verbose_name_plural": "team draws",
},
),
migrations.AlterField(
model_name="teamdraw",
name="choose_index",
field=models.PositiveSmallIntegerField(
choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)],
default=None,
null=True,
verbose_name="choose index",
),
),
migrations.AlterField(
model_name="teamdraw",
name="passage_index",
field=models.PositiveSmallIntegerField(
choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)],
default=None,
null=True,
verbose_name="passage index",
),
),
]

View File

@ -4,7 +4,8 @@
from asgiref.sync import sync_to_async from asgiref.sync import sync_to_async
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.utils.text import format_lazy from django.urls import reverse_lazy
from django.utils.text import format_lazy, slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from participation.models import Passage, Participation, Pool as PPool, Tournament from participation.models import Passage, Participation, Pool as PPool, Tournament
@ -32,6 +33,9 @@ class Draw(models.Model):
verbose_name=_("last message"), verbose_name=_("last message"),
) )
def get_absolute_url(self):
return reverse_lazy('draw:index') + f'#{slugify(self.tournament.name)}'
@property @property
def exportable(self): def exportable(self):
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())
@ -110,6 +114,9 @@ class Draw(models.Model):
async def ainformation(self): async def ainformation(self):
return await sync_to_async(lambda: self.information)() return await sync_to_async(lambda: self.information)()
def __str__(self):
return str(format_lazy(_("Draw of tournament {tournament}"), tournament=self.tournament.name))
class Meta: class Meta:
verbose_name = _('draw') verbose_name = _('draw')
verbose_name_plural = _('draws') verbose_name_plural = _('draws')
@ -153,6 +160,7 @@ class Round(models.Model):
class Meta: class Meta:
verbose_name = _('round') verbose_name = _('round')
verbose_name_plural = _('rounds') verbose_name_plural = _('rounds')
ordering = ('draw__tournament__name', 'number',)
class Pool(models.Model): class Pool(models.Model):
@ -265,11 +273,12 @@ class Pool(models.Model):
) )
def __str__(self): def __str__(self):
return f"{self.get_letter_display()}{self.round.number}" return str(format_lazy(_("Pool {letter}{number}"), letter=self.get_letter_display(), number=self.round.number))
class Meta: class Meta:
verbose_name = _('pool') verbose_name = _('pool')
verbose_name_plural = _('pools') verbose_name_plural = _('pools')
ordering = ('round__draw__tournament__name', 'round__number', 'letter',)
class TeamDraw(models.Model): class TeamDraw(models.Model):
@ -294,14 +303,14 @@ class TeamDraw(models.Model):
) )
passage_index = models.PositiveSmallIntegerField( passage_index = models.PositiveSmallIntegerField(
choices=zip(range(1, 5), range(1, 5)), choices=zip(range(1, 6), range(1, 6)),
null=True, null=True,
default=None, default=None,
verbose_name=_('passage index'), verbose_name=_('passage index'),
) )
choose_index = models.PositiveSmallIntegerField( choose_index = models.PositiveSmallIntegerField(
choices=zip(range(1, 5), range(1, 5)), choices=zip(range(1, 6), range(1, 6)),
null=True, null=True,
default=None, default=None,
verbose_name=_('choose index'), verbose_name=_('choose index'),
@ -356,6 +365,13 @@ class TeamDraw(models.Model):
def penalty(self): def penalty(self):
return 0.5 * self.penalty_int return 0.5 * self.penalty_int
def __str__(self):
return str(format_lazy(_("Draw of the team {trigram} for the pool {letter}{number}"),
trigram=self.participation.team.trigram,
letter=self.pool.get_letter_display() if self.pool else "",
number=self.round.number))
class Meta: class Meta:
verbose_name = _('team draw') verbose_name = _('team draw')
verbose_name_plural = _('team draws') verbose_name_plural = _('team draws')
ordering = ('round__draw__tournament__name', 'round__number', 'pool__letter', 'passage_index',)

View File

@ -67,7 +67,7 @@
<li id="recap-{{ tournament.id }}-round-{{ round.number }}-pool-{{ pool.get_letter_display }}" <li id="recap-{{ tournament.id }}-round-{{ round.number }}-pool-{{ pool.get_letter_display }}"
class="list-group-item px-3 py-3 {% if tournament.draw.current_round.current_pool == pool %} list-group-item-success{% endif %}" class="list-group-item px-3 py-3 {% if tournament.draw.current_round.current_pool == pool %} list-group-item-success{% endif %}"
data-tournament="{{ tournament.id }}"> data-tournament="{{ tournament.id }}">
<strong>{% trans "pool"|capfirst %} {{ pool }}</strong> <strong>{{ pool }}</strong>
<ul id="recap-{{ tournament.id }}-round-{{ round.number }}-pool-{{ pool.get_letter_display }}-team-list" <ul id="recap-{{ tournament.id }}-round-{{ round.number }}-pool-{{ pool.get_letter_display }}-team-list"
class="list-group list-group-flush"> class="list-group list-group-flush">
{% for td in pool.team_draws.all %} {% for td in pool.team_draws.all %}
@ -182,7 +182,7 @@
<div class="card w-100 my-3 order-{{ pool.letter }}"> <div class="card w-100 my-3 order-{{ pool.letter }}">
<div class="card-header"> <div class="card-header">
<h3> <h3>
{% trans "pool"|capfirst %} {{ pool }} {{ pool }}
</h3> </h3>
</div> </div>
<div class="card-body"> <div class="card-body">

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-31 17:39+0200\n" "POT-Creation-Date: 2023-04-03 17:59+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -21,6 +21,22 @@ msgstr ""
msgid "API" msgid "API"
msgstr "API" msgstr "API"
#: draw/admin.py:16 draw/admin.py:28 draw/admin.py:44
#: participation/models.py:126 participation/tables.py:86
msgid "teams"
msgstr "équipes"
#: draw/admin.py:40 draw/admin.py:56 draw/models.py:17
#: participation/models.py:295 participation/models.py:319
#: participation/models.py:351
msgid "tournament"
msgstr "tournoi"
#: draw/admin.py:60 draw/models.py:157 draw/models.py:290
#: participation/models.py:355
msgid "round"
msgstr "tour"
#: draw/apps.py:10 tfjm/templates/base.html:97 #: draw/apps.py:10 tfjm/templates/base.html:97
msgid "Draw" msgid "Draw"
msgstr "Tirage au sort" msgstr "Tirage au sort"
@ -80,11 +96,6 @@ msgstr ""
msgid "This is only available for the final tournament." msgid "This is only available for the final tournament."
msgstr "Cela n'est possible que pour la finale." msgstr "Cela n'est possible que pour la finale."
#: draw/models.py:17 participation/models.py:295 participation/models.py:319
#: participation/models.py:351
msgid "tournament"
msgstr "tournoi"
#: draw/models.py:26 #: draw/models.py:26
msgid "current round" msgid "current round"
msgstr "tour actuel" msgstr "tour actuel"
@ -93,106 +104,116 @@ msgstr "tour actuel"
msgid "last message" msgid "last message"
msgstr "dernier message" msgstr "dernier message"
#: draw/models.py:114 draw/models.py:122 #: draw/models.py:114
#, python-brace-format
msgid "Draw of tournament {tournament}"
msgstr "Tirage au sort du tournoi {tournament}"
#: draw/models.py:117 draw/models.py:125
msgid "draw" msgid "draw"
msgstr "tirage au sort" msgstr "tirage au sort"
#: draw/models.py:115 #: draw/models.py:118
msgid "draws" msgid "draws"
msgstr "tirages au sort" msgstr "tirages au sort"
#: draw/models.py:127 #: draw/models.py:130
msgid "Round 1" msgid "Round 1"
msgstr "Tour 1" msgstr "Tour 1"
#: draw/models.py:128 #: draw/models.py:131
msgid "Round 2" msgid "Round 2"
msgstr "Tour 2" msgstr "Tour 2"
#: draw/models.py:130 #: draw/models.py:133
msgid "number" msgid "number"
msgstr "numéro" msgstr "numéro"
#: draw/models.py:139 #: draw/models.py:142
msgid "current pool" msgid "current pool"
msgstr "poule actuelle" msgstr "poule actuelle"
#: draw/models.py:154 draw/models.py:285 participation/models.py:355 #: draw/models.py:158
msgid "round"
msgstr "tour"
#: draw/models.py:155
msgid "rounds" msgid "rounds"
msgstr "tours" msgstr "tours"
#: draw/models.py:171 participation/models.py:369 #: draw/models.py:175 participation/models.py:369
msgid "letter" msgid "letter"
msgstr "lettre" msgstr "lettre"
#: draw/models.py:175 #: draw/models.py:179
#: participation/templates/participation/tournament_detail.html:15 #: participation/templates/participation/tournament_detail.html:15
msgid "size" msgid "size"
msgstr "taille" msgstr "taille"
#: draw/models.py:184 #: draw/models.py:188
msgid "current team" msgid "current team"
msgstr "équipe actuelle" msgstr "équipe actuelle"
#: draw/models.py:193 #: draw/models.py:197
msgid "associated pool" msgid "associated pool"
msgstr "poule associée" msgstr "poule associée"
#: draw/models.py:271 draw/models.py:293 #: draw/models.py:272
#: draw/templates/draw/tournament_content.html:70 #, python-brace-format
#: draw/templates/draw/tournament_content.html:185 participation/models.py:417 msgid "Pool {letter}{number}"
msgstr "Poule {letter}{number}"
#: draw/models.py:275 draw/models.py:298
#: draw/templates/draw/tournament_content.html:70 participation/models.py:417
#: participation/models.py:426 participation/tables.py:82 #: participation/models.py:426 participation/tables.py:82
msgid "pool" msgid "pool"
msgstr "poule" msgstr "poule"
#: draw/models.py:272 participation/models.py:418 #: draw/models.py:276 participation/models.py:418
msgid "pools" msgid "pools"
msgstr "poules" msgstr "poules"
#: draw/models.py:279 participation/models.py:342 participation/models.py:550 #: draw/models.py:284 participation/models.py:342 participation/models.py:550
#: participation/models.py:580 participation/models.py:618 #: participation/models.py:580 participation/models.py:618
msgid "participation" msgid "participation"
msgstr "participation" msgstr "participation"
#: draw/models.py:300 #: draw/models.py:305
msgid "passage index" msgid "passage index"
msgstr "numéro de passage" msgstr "numéro de passage"
#: draw/models.py:307 #: draw/models.py:312
msgid "choose index" msgid "choose index"
msgstr "numéro de choix" msgstr "numéro de choix"
#: draw/models.py:312 draw/models.py:335 participation/models.py:433 #: draw/models.py:317 draw/models.py:340 participation/models.py:433
#: participation/models.py:587 #: participation/models.py:587
#, python-brace-format #, python-brace-format
msgid "Problem #{problem}" msgid "Problem #{problem}"
msgstr "Problème n°{problem}" msgstr "Problème n°{problem}"
#: draw/models.py:316 draw/models.py:339 #: draw/models.py:321 draw/models.py:344
msgid "accepted problem" msgid "accepted problem"
msgstr "problème accepté" msgstr "problème accepté"
#: draw/models.py:323 #: draw/models.py:328
msgid "passage dice" msgid "passage dice"
msgstr "dé d'ordre passage" msgstr "dé d'ordre de passage"
#: draw/models.py:330 #: draw/models.py:335
msgid "choice dice" msgid "choice dice"
msgstr "dé d'ordre de choix" msgstr "dé d'ordre de choix"
#: draw/models.py:344 #: draw/models.py:349
msgid "rejected problems" msgid "rejected problems"
msgstr "problèmes rejetés" msgstr "problèmes rejetés"
#: draw/models.py:360 #: draw/models.py:365
#, python-brace-format
msgid "Draw of the team {trigram} for the pool {letter}{number}"
msgstr "Tirage de l'équipe {trigram} pour la poule {letter}{number}"
#: draw/models.py:371
msgid "team draw" msgid "team draw"
msgstr "tirage d'équipe" msgstr "tirage d'équipe"
#: draw/models.py:361 #: draw/models.py:372
msgid "team draws" msgid "team draws"
msgstr "tirages d'équipe" msgstr "tirages d'équipe"
@ -339,7 +360,7 @@ msgstr "Ce trigramme est déjà utilisé."
msgid "No team was found with this access code." msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès." msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: participation/forms.py:81 participation/forms.py:287 #: participation/forms.py:81 participation/forms.py:289
#: registration/forms.py:113 registration/forms.py:135 #: registration/forms.py:113 registration/forms.py:135
#: registration/forms.py:157 registration/forms.py:179 #: registration/forms.py:157 registration/forms.py:179
#: registration/forms.py:224 #: registration/forms.py:224
@ -364,7 +385,7 @@ msgstr "Message à adresser à l'équipe :"
msgid "The uploaded file size must be under 5 Mo." msgid "The uploaded file size must be under 5 Mo."
msgstr "Le fichier envoyé doit peser moins de 5 Mo." msgstr "Le fichier envoyé doit peser moins de 5 Mo."
#: participation/forms.py:153 participation/forms.py:289 #: participation/forms.py:153 participation/forms.py:291
msgid "The uploaded file must be a PDF file." msgid "The uploaded file must be a PDF file."
msgstr "Le fichier envoyé doit être au format PDF." msgstr "Le fichier envoyé doit être au format PDF."
@ -383,20 +404,20 @@ msgstr ""
"Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au " "Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au "
"format CSV." "format CSV."
#: participation/forms.py:245 #: participation/forms.py:247
msgid "The following note is higher of the maximum expected value:" msgid "The following note is higher of the maximum expected value:"
msgstr "La note suivante est supérieure au maximum attendu :" msgstr "La note suivante est supérieure au maximum attendu :"
#: participation/forms.py:253 #: participation/forms.py:255
msgid "The following user was not found:" msgid "The following user was not found:"
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :" msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
#: participation/forms.py:270 #: participation/forms.py:272
msgid "The defender, the opponent and the reporter must be different." msgid "The defender, the opponent and the reporter must be different."
msgstr "" msgstr ""
"Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es." "Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es."
#: participation/forms.py:274 #: participation/forms.py:276
msgid "This defender did not work on this problem." msgid "This defender did not work on this problem."
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème." msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
@ -430,10 +451,6 @@ msgstr "lettre de motivation"
msgid "Team {name} ({trigram})" msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})" msgstr "Équipe {name} ({trigram})"
#: participation/models.py:126 participation/tables.py:86
msgid "teams"
msgstr "équipes"
#: participation/models.py:140 #: participation/models.py:140
msgid "start" msgid "start"
msgstr "début" msgstr "début"