1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2024-12-25 05:42:23 +00:00

Register pools

This commit is contained in:
Yohann D'ANELLO 2021-01-13 17:00:50 +01:00
parent 4faec03efb
commit 4d83664c0d
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
10 changed files with 91 additions and 12 deletions

View File

@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError
from django.utils import formats from django.utils import formats
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import Participation, Team, Tournament, Solution from .models import Participation, Team, Tournament, Solution, Pool
class TeamForm(forms.ModelForm): class TeamForm(forms.ModelForm):
@ -123,3 +123,9 @@ class SolutionForm(forms.ModelForm):
class Meta: class Meta:
model = Solution model = Solution
fields = ('problem', 'file',) fields = ('problem', 'file',)
class PoolForm(forms.ModelForm):
class Meta:
model = Pool
fields = ('tournament', 'round', 'juries',)

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.11 on 2021-01-13 16:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('participation', '0007_auto_20210112_1801'),
]
operations = [
migrations.AlterField(
model_name='pool',
name='round',
field=models.PositiveSmallIntegerField(choices=[(1, 'Round 1'), (2, 'Round 2')], verbose_name='round'),
),
]

View File

@ -288,6 +288,10 @@ class Pool(models.Model):
round = models.PositiveSmallIntegerField( round = models.PositiveSmallIntegerField(
verbose_name=_("round"), verbose_name=_("round"),
choices=[
(1, format_lazy(_("Round {round}"), round=1)),
(2, format_lazy(_("Round {round}"), round=2)),
]
) )
participations = models.ManyToManyField( participations = models.ManyToManyField(
@ -306,6 +310,9 @@ class Pool(models.Model):
def solutions(self): def solutions(self):
return Solution.objects.filter(participation__in=self.participations, final_solution=self.tournament.final) return Solution.objects.filter(participation__in=self.participations, final_solution=self.tournament.final)
def get_absolute_url(self):
return reverse_lazy("participation:pool_detail", args=(self.pk,))
def __str__(self): def __str__(self):
return _("Pool {round} for tournament {tournament} with teams {teams}")\ return _("Pool {round} for tournament {tournament} with teams {teams}")\
.format(round=self.round, .format(round=self.round,

View File

@ -81,12 +81,13 @@ class PoolTable(tables.Table):
teams = tables.LinkColumn( teams = tables.LinkColumn(
'participation:pool_detail', 'participation:pool_detail',
args=[tables.A('id')], args=[tables.A('id')],
verbose_name=_("teams"), verbose_name=_("teams").capitalize,
accessor=None, empty_values=(),
) )
def render_teams(self, record): def render_teams(self, record):
return ", ".join(participation.team.trigram for participation in record.participations.all()) return ", ".join(participation.team.trigram for participation in record.participations.all()) \
or _("No defined team")
class Meta: class Meta:
attrs = { attrs = {

View File

@ -50,7 +50,6 @@
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('button[data-target="#uploadSolutionModal"]').click(function() { $('button[data-target="#uploadSolutionModal"]').click(function() {
console.log(42)
let modalBody = $("#uploadSolutionModal div.modal-body"); let modalBody = $("#uploadSolutionModal div.modal-body");
if (!modalBody.html().trim()) if (!modalBody.html().trim())
modalBody.load("{% url "participation:upload_solution" pk=participation.pk %} #form-content") modalBody.load("{% url "participation:upload_solution" pk=participation.pk %} #form-content")

View File

@ -0,0 +1 @@
{% extends "base.html" %}

View File

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load crispy_forms_filters i18n %}
{% block content %}
<form method="post" enctype="multipart/form-data">
<div id="form-content">
{% csrf_token %}
{{ form|crispy }}
</div>
<button class="btn btn-primary" type="submit">{% trans "Update pool" %}</button>
</form>
{% endblock content %}

View File

@ -69,6 +69,23 @@
</div> </div>
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
<a class="btn btn-block btn-success" href="#">{% trans "Add new pool" %}</a> <button class="btn btn-block btn-success" data-toggle="modal" data-target="#addPoolModal">{% trans "Add new pool" %}</button>
{% endif %} {% endif %}
{% trans "Add pool" as modal_title %}
{% trans "Add" as modal_button %}
{% url "participation:pool_create" as modal_action %}
{% include "base_modal.html" with modal_id="addPool" %}
{% endblock %}
{% block extrajavascript %}
<script>
$(document).ready(function () {
$('button[data-target="#addPoolModal"]').click(function() {
let modalBody = $("#addPoolModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:pool_create" %} #form-content")
});
});
</script>
{% endblock %} {% endblock %}

View File

@ -5,9 +5,9 @@ from django.urls import path
from django.views.generic import TemplateView from django.views.generic import TemplateView
from .views import CreateTeamView, JoinTeamView, \ from .views import CreateTeamView, JoinTeamView, \
MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, TeamAuthorizationsView, \ MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, PoolCreateView, PoolDetailView, \
TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, TournamentCreateView, TournamentDetailView, \ PoolUpdateView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
TournamentListView, TournamentUpdateView, SolutionUploadView TournamentCreateView, TournamentDetailView, TournamentListView, TournamentUpdateView, SolutionUploadView
app_name = "participation" app_name = "participation"
@ -28,5 +28,8 @@ urlpatterns = [
path("tournament/create/", TournamentCreateView.as_view(), name="tournament_create"), path("tournament/create/", TournamentCreateView.as_view(), name="tournament_create"),
path("tournament/<int:pk>/", TournamentDetailView.as_view(), name="tournament_detail"), path("tournament/<int:pk>/", TournamentDetailView.as_view(), name="tournament_detail"),
path("tournament/<int:pk>/update/", TournamentUpdateView.as_view(), name="tournament_update"), path("tournament/<int:pk>/update/", TournamentUpdateView.as_view(), name="tournament_update"),
path("pools/create/", PoolCreateView.as_view(), name="pool_create"),
path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat") path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat")
] ]

View File

@ -23,9 +23,9 @@ from tfjm.lists import get_sympa_client
from tfjm.matrix import Matrix from tfjm.matrix import Matrix
from tfjm.views import AdminMixin from tfjm.views import AdminMixin
from .forms import JoinTeamForm, ParticipationForm, RequestValidationForm, SolutionForm, TeamForm, TournamentForm, \ from .forms import JoinTeamForm, ParticipationForm, PoolForm, RequestValidationForm, SolutionForm, TeamForm,\
ValidateParticipationForm TournamentForm, ValidateParticipationForm
from .models import Participation, Team, Tournament, Solution from .models import Participation, Team, Tournament, Solution, Pool
from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable
@ -468,3 +468,17 @@ class SolutionUploadView(LoginRequiredMixin, FormView):
def get_success_url(self): def get_success_url(self):
return reverse_lazy("participation:participation_detail", args=(self.participation.pk,)) return reverse_lazy("participation:participation_detail", args=(self.participation.pk,))
class PoolCreateView(AdminMixin, CreateView):
model = Pool
form_class = PoolForm
class PoolDetailView(AdminMixin, DetailView):
model = Pool
class PoolUpdateView(AdminMixin, UpdateView):
model = Pool
form_class = PoolForm