mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2024-12-24 18:22:24 +00:00
Upload solution is working
This commit is contained in:
parent
09e5a72470
commit
2ca0444053
@ -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
|
from .models import Participation, Team, Tournament, Solution
|
||||||
|
|
||||||
|
|
||||||
class TeamForm(forms.ModelForm):
|
class TeamForm(forms.ModelForm):
|
||||||
@ -112,3 +112,14 @@ class TournamentForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Tournament
|
model = Tournament
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class SolutionForm(forms.ModelForm):
|
||||||
|
def save(self, commit=True):
|
||||||
|
"""
|
||||||
|
Don't save a solution with this way. Use a view instead
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Solution
|
||||||
|
fields = ('problem', 'file',)
|
||||||
|
18
apps/participation/migrations/0006_participation_final.py
Normal file
18
apps/participation/migrations/0006_participation_final.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.11 on 2021-01-12 16:07
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('participation', '0005_auto_20210101_1149'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='participation',
|
||||||
|
name='final',
|
||||||
|
field=models.BooleanField(default=False, help_text='The team is selected for the final tournament.', verbose_name='selected for final'),
|
||||||
|
),
|
||||||
|
]
|
@ -259,6 +259,12 @@ class Participation(models.Model):
|
|||||||
help_text=_("The participation got the validation of the organizers."),
|
help_text=_("The participation got the validation of the organizers."),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
final = models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("selected for final"),
|
||||||
|
help_text=_("The team is selected for the final tournament."),
|
||||||
|
)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy("participation:participation_detail", args=(self.pk,))
|
return reverse_lazy("participation:participation_detail", args=(self.pk,))
|
||||||
|
|
||||||
|
@ -28,5 +28,26 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadSolutionModal">{% trans "Upload solution" %}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% trans "Upload solution" as modal_title %}
|
||||||
|
{% trans "Upload" as modal_button %}
|
||||||
|
{% url "participation:upload_solution" pk=participation.pk as modal_action %}
|
||||||
|
{% include "base_modal.html" with modal_id="uploadSolution" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extrajavascript %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('button[data-target="#uploadSolutionModal"]').click(function() {
|
||||||
|
console.log(42)
|
||||||
|
let modalBody = $("#uploadSolutionModal div.modal-body");
|
||||||
|
if (!modalBody.html().trim())
|
||||||
|
modalBody.load("{% url "participation:upload_solution" pk=participation.pk %} #form-content")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load crispy_forms_filters i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post">
|
||||||
|
<div id="form-content">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans "Upload" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
@ -7,7 +7,7 @@ from django.views.generic import TemplateView
|
|||||||
from .views import CreateTeamView, JoinTeamView, \
|
from .views import CreateTeamView, JoinTeamView, \
|
||||||
MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, TeamAuthorizationsView, \
|
MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, TeamAuthorizationsView, \
|
||||||
TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, TournamentCreateView, TournamentDetailView, \
|
TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, TournamentCreateView, TournamentDetailView, \
|
||||||
TournamentListView, TournamentUpdateView
|
TournamentListView, TournamentUpdateView, SolutionUploadView
|
||||||
|
|
||||||
|
|
||||||
app_name = "participation"
|
app_name = "participation"
|
||||||
@ -23,6 +23,7 @@ urlpatterns = [
|
|||||||
path("team/leave/", TeamLeaveView.as_view(), name="team_leave"),
|
path("team/leave/", TeamLeaveView.as_view(), name="team_leave"),
|
||||||
path("detail/", MyParticipationDetailView.as_view(), name="my_participation_detail"),
|
path("detail/", MyParticipationDetailView.as_view(), name="my_participation_detail"),
|
||||||
path("detail/<int:pk>/", ParticipationDetailView.as_view(), name="participation_detail"),
|
path("detail/<int:pk>/", ParticipationDetailView.as_view(), name="participation_detail"),
|
||||||
|
path("detail/<int:pk>/solution/", SolutionUploadView.as_view(), name="upload_solution"),
|
||||||
path("tournament/", TournamentListView.as_view(), name="tournament_list"),
|
path("tournament/", TournamentListView.as_view(), name="tournament_list"),
|
||||||
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"),
|
||||||
|
@ -9,7 +9,7 @@ from django.contrib.sites.models import Site
|
|||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse, Http404
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
@ -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, TeamForm, ValidateParticipationForm, \
|
from .forms import JoinTeamForm, ParticipationForm, RequestValidationForm, SolutionForm, TeamForm, TournamentForm, \
|
||||||
TournamentForm
|
ValidateParticipationForm
|
||||||
from .models import Participation, Team, Tournament
|
from .models import Participation, Team, Tournament, Solution
|
||||||
from .tables import TeamTable, TournamentTable, ParticipationTable
|
from .tables import TeamTable, TournamentTable, ParticipationTable
|
||||||
|
|
||||||
|
|
||||||
@ -435,3 +435,36 @@ class TournamentDetailView(DetailView):
|
|||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["teams"] = ParticipationTable(self.object.participations.all())
|
context["teams"] = ParticipationTable(self.object.participations.all())
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class SolutionUploadView(LoginRequiredMixin, FormView):
|
||||||
|
template_name = "participation/upload_solution.html"
|
||||||
|
form_class = SolutionForm
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
qs = Participation.objects.filter(pk=self.kwargs["pk"])
|
||||||
|
if not qs.exists():
|
||||||
|
raise Http404
|
||||||
|
self.participation = qs.get()
|
||||||
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
"""
|
||||||
|
When a solution is submitted, it replaces a previous solution if existing,
|
||||||
|
otherwise it creates a new solution.
|
||||||
|
It is discriminating whenever the team is selected for the final tournament or not.
|
||||||
|
"""
|
||||||
|
form_sol = form.instance
|
||||||
|
# Drop previous solution if existing
|
||||||
|
Solution.objects.filter(
|
||||||
|
participation=self.participation,
|
||||||
|
problem=form_sol.problem,
|
||||||
|
final_solution=self.participation.final,
|
||||||
|
).delete()
|
||||||
|
form_sol.participation = self.participation
|
||||||
|
form_sol.final = self.participation.final
|
||||||
|
form_sol.save()
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse_lazy("participation:participation_detail", args=(self.participation.pk,))
|
||||||
|
Loading…
Reference in New Issue
Block a user