mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 09:42:10 +01:00 
			
		
		
		
	Display detail about a passage
This commit is contained in:
		@@ -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, Pool
 | 
					from .models import Participation, Passage, Pool, Team, Tournament, Solution
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TeamForm(forms.ModelForm):
 | 
					class TeamForm(forms.ModelForm):
 | 
				
			||||||
@@ -145,3 +145,20 @@ class PoolTeamsForm(forms.ModelForm):
 | 
				
			|||||||
        widgets = {
 | 
					        widgets = {
 | 
				
			||||||
            "participations": forms.CheckboxSelectMultiple,
 | 
					            "participations": forms.CheckboxSelectMultiple,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PassageForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    def clean(self):
 | 
				
			||||||
 | 
					        cleaned_data = super().clean()
 | 
				
			||||||
 | 
					        if "defender" in cleaned_data and "opponent" in cleaned_data and "reporter" in cleaned_data \
 | 
				
			||||||
 | 
					                and len({cleaned_data["defender"], cleaned_data["opponent"], cleaned_data["reporter"]}) < 3:
 | 
				
			||||||
 | 
					            self.add_error(None, _("The defender, the opponent and the reporter must be different."))
 | 
				
			||||||
 | 
					        if "defender" in self.cleaned_data and "solution_number" in self.cleaned_data \
 | 
				
			||||||
 | 
					                and not Solution.objects.filter(participation=cleaned_data["defender"],
 | 
				
			||||||
 | 
					                                                problem=cleaned_data["solution_number"]).exists():
 | 
				
			||||||
 | 
					            self.add_error("solution_number", _("This defender did not work on this problem."))
 | 
				
			||||||
 | 
					        return cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Passage
 | 
				
			||||||
 | 
					        fields = ('solution_number', 'place', 'defender', 'opponent', 'reporter',)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -340,6 +340,13 @@ class Passage(models.Model):
 | 
				
			|||||||
        default="Non indiqué",
 | 
					        default="Non indiqué",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    solution_number = models.PositiveSmallIntegerField(
 | 
				
			||||||
 | 
					        verbose_name=_("defended solution"),
 | 
				
			||||||
 | 
					        choices=[
 | 
				
			||||||
 | 
					            (i, format_lazy(_("Problem #{problem}"), problem=i)) for i in range(1, settings.PROBLEM_COUNT + 1)
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    defender = models.ForeignKey(
 | 
					    defender = models.ForeignKey(
 | 
				
			||||||
        Participation,
 | 
					        Participation,
 | 
				
			||||||
        on_delete=models.PROTECT,
 | 
					        on_delete=models.PROTECT,
 | 
				
			||||||
@@ -361,6 +368,16 @@ class Passage(models.Model):
 | 
				
			|||||||
        related_name="+",
 | 
					        related_name="+",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def defended_solution(self) -> "Solution":
 | 
				
			||||||
 | 
					        return Solution.objects.get(
 | 
				
			||||||
 | 
					            participation=self.defender,
 | 
				
			||||||
 | 
					            problem=self.solution_number,
 | 
				
			||||||
 | 
					            final_solution=self.pool.tournament.final)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_absolute_url(self):
 | 
				
			||||||
 | 
					        return reverse_lazy("participation:passage_detail", args=(self.pk,))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean(self):
 | 
					    def clean(self):
 | 
				
			||||||
        if self.defender not in self.pool.participations.all():
 | 
					        if self.defender not in self.pool.participations.all():
 | 
				
			||||||
            raise ValidationError(_("Team {trigram} is not registered in the pool.")
 | 
					            raise ValidationError(_("Team {trigram} is not registered in the pool.")
 | 
				
			||||||
@@ -373,6 +390,10 @@ class Passage(models.Model):
 | 
				
			|||||||
                                  .format(trigram=self.reporter.team.trigram))
 | 
					                                  .format(trigram=self.reporter.team.trigram))
 | 
				
			||||||
        return super().clean()
 | 
					        return super().clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return _("Passage of {defender} for problem {problem}")\
 | 
				
			||||||
 | 
					            .format(defender=self.defender.team, problem=self.solution_number)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        verbose_name = _("passage")
 | 
					        verbose_name = _("passage")
 | 
				
			||||||
        verbose_name_plural = _("passages")
 | 
					        verbose_name_plural = _("passages")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					{% trans "any" as any %}
 | 
				
			||||||
 | 
					    <div class="card bg-light shadow">
 | 
				
			||||||
 | 
					        <div class="card-header text-center">
 | 
				
			||||||
 | 
					            <h4>{{ passage }}</h4>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="card-body">
 | 
				
			||||||
 | 
					            <dl class="row">
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Pool:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9"><a href="{{ passage.pool.get_absolute_url }}">{{ passage.pool }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Defender:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9"><a href="{{ passage.defender.get_absolute_url }}">{{ passage.defender.team }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Opponent:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9"><a href="{{ passage.opponent.get_absolute_url }}">{{ passage.opponent.team }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Reporter:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9"><a href="{{ passage.reporter.get_absolute_url }}">{{ passage.reporter.team }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Defended solution:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9"><a href="{{ passage.defended_solution.file.url }}" data-turbolinks="false">{{ passage.defended_solution }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Place:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9">{{ passage.place }}</dd>
 | 
				
			||||||
 | 
					            </dl>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {% if user.registration.is_admin %}
 | 
				
			||||||
 | 
					            <div class="card-footer text-center">
 | 
				
			||||||
 | 
					                <button class="btn btn-primary" data-toggle="modal" data-target="#updatePassageModal">{% trans "Update" %}</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        {% endif %}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {% trans "Update passage" as modal_title %}
 | 
				
			||||||
 | 
					    {% trans "Update" as modal_button %}
 | 
				
			||||||
 | 
					    {% url "participation:passage_update" pk=passage.pk as modal_action %}
 | 
				
			||||||
 | 
					    {% include "base_modal.html" with modal_id="updatePassage" %}
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block extrajavascript %}
 | 
				
			||||||
 | 
					    <script>
 | 
				
			||||||
 | 
					        $(document).ready(function () {
 | 
				
			||||||
 | 
					            $('button[data-target="#updatePassageModal"]').click(function() {
 | 
				
			||||||
 | 
					                let modalBody = $("#updatePassageModal div.modal-body");
 | 
				
			||||||
 | 
					                if (!modalBody.html().trim())
 | 
				
			||||||
 | 
					                    modalBody.load("{% url "participation:passage_update" pk=passage.pk %} #form-content")
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    </script>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
							
								
								
									
										13
									
								
								apps/participation/templates/participation/passage_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								apps/participation/templates/participation/passage_form.html
									
									
									
									
									
										Normal file
									
								
							@@ -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 "Update passage" %}</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					{% endblock content %}
 | 
				
			||||||
@@ -9,31 +9,50 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="card-body">
 | 
					        <div class="card-body">
 | 
				
			||||||
            <dl class="row">
 | 
					            <dl class="row">
 | 
				
			||||||
                <dt class="col-sm-2">{% trans "Tournament:" %}</dt>
 | 
					                <dt class="col-sm-3">{% trans "Tournament:" %}</dt>
 | 
				
			||||||
                <dd class="col-sm-10">{{ pool.tournament }}</dd>
 | 
					                <dd class="col-sm-9">{{ pool.tournament }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <dt class="col-sm-2">{% trans "Round:" %}</dt>
 | 
					                <dt class="col-sm-3">{% trans "Round:" %}</dt>
 | 
				
			||||||
                <dd class="col-sm-10">{{ pool.get_round_display }}</dd>
 | 
					                <dd class="col-sm-9">{{ pool.get_round_display }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <dt class="col-sm-2">{% trans "Teams:" %}</dt>
 | 
					                <dt class="col-sm-3">{% trans "Teams:" %}</dt>
 | 
				
			||||||
                <dd class="col-sm-10">
 | 
					                <dd class="col-sm-9">
 | 
				
			||||||
                    {% for participation in pool.participations.all %}
 | 
					                    {% for participation in pool.participations.all %}
 | 
				
			||||||
                        <a href="{{ participation.get_absolute_url }}" data-turbolinks="false">{{ participation.team }}{% if not forloop.last %}, {% endif %}</a>
 | 
					                        <a href="{{ participation.get_absolute_url }}" data-turbolinks="false">{{ participation.team }}{% if not forloop.last %}, {% endif %}</a>
 | 
				
			||||||
                    {% endfor %}
 | 
					                    {% endfor %}
 | 
				
			||||||
                </dd>
 | 
					                </dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <dt class="col-sm-2">{% trans "Juries:" %}</dt>
 | 
					                <dt class="col-sm-3">{% trans "Juries:" %}</dt>
 | 
				
			||||||
                <dd class="col-sm-10">{{ pool.juries.all|join:", " }}</dd>
 | 
					                <dd class="col-sm-9">{{ pool.juries.all|join:", " }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Passages:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9">
 | 
				
			||||||
 | 
					                    {% for passage in pool.passages.all %}
 | 
				
			||||||
 | 
					                        <a href="{{ passage.get_absolute_url }}" data-turbolinks="false">{{ passage }}{% if not forloop.last %}, {% endif %}</a>
 | 
				
			||||||
 | 
					                    {% endfor %}
 | 
				
			||||||
 | 
					                </dd>
 | 
				
			||||||
 | 
					                <dt class="col-sm-3">{% trans "Defended solutions:" %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-sm-9">
 | 
				
			||||||
 | 
					                    {% for passage in pool.passages.all %}
 | 
				
			||||||
 | 
					                        <a href="{{ passage.defended_solution.get_absolute_url }}" data-turbolinks="false">{{ passage.defended_solution }}{% if not forloop.last %}, {% endif %}</a>
 | 
				
			||||||
 | 
					                    {% endfor %}
 | 
				
			||||||
 | 
					                </dd>
 | 
				
			||||||
            </dl>
 | 
					            </dl>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        {% if user.registration.is_admin %}
 | 
					        {% if user.registration.is_admin %}
 | 
				
			||||||
            <div class="card-footer text-center">
 | 
					            <div class="card-footer text-center">
 | 
				
			||||||
 | 
					                <button class="btn btn-success" data-toggle="modal" data-target="#addPassageModal">{% trans "Add passage" %}</button>
 | 
				
			||||||
                <button class="btn btn-primary" data-toggle="modal" data-target="#updatePoolModal">{% trans "Update" %}</button>
 | 
					                <button class="btn btn-primary" data-toggle="modal" data-target="#updatePoolModal">{% trans "Update" %}</button>
 | 
				
			||||||
                <button class="btn btn-primary" data-toggle="modal" data-target="#updateTeamsModal">{% trans "Update teams" %}</button>
 | 
					                <button class="btn btn-primary" data-toggle="modal" data-target="#updateTeamsModal">{% trans "Update teams" %}</button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {% trans "Add passage" as modal_title %}
 | 
				
			||||||
 | 
					    {% trans "Add" as modal_button %}
 | 
				
			||||||
 | 
					    {% url "participation:passage_create" pk=pool.pk as modal_action %}
 | 
				
			||||||
 | 
					    {% include "base_modal.html" with modal_id="addPassage" modal_button_type="success" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {% trans "Update pool" as modal_title %}
 | 
					    {% trans "Update pool" as modal_title %}
 | 
				
			||||||
    {% trans "Update" as modal_button %}
 | 
					    {% trans "Update" as modal_button %}
 | 
				
			||||||
    {% url "participation:pool_update" pk=pool.pk as modal_action %}
 | 
					    {% url "participation:pool_update" pk=pool.pk as modal_action %}
 | 
				
			||||||
@@ -59,6 +78,12 @@
 | 
				
			|||||||
                if (!modalBody.html().trim())
 | 
					                if (!modalBody.html().trim())
 | 
				
			||||||
                    modalBody.load("{% url "participation:pool_update_teams" pk=pool.pk %} #form-content")
 | 
					                    modalBody.load("{% url "participation:pool_update_teams" pk=pool.pk %} #form-content")
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $('button[data-target="#addPassageModal"]').click(function() {
 | 
				
			||||||
 | 
					                let modalBody = $("#addPassageModal div.modal-body");
 | 
				
			||||||
 | 
					                if (!modalBody.html().trim())
 | 
				
			||||||
 | 
					                    modalBody.load("{% url "participation:passage_create" pk=pool.pk %} #form-content")
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    </script>
 | 
					    </script>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,8 @@ 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, PoolCreateView, PoolDetailView, \
 | 
					    MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, \
 | 
				
			||||||
 | 
					    PassageCreateView, PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, \
 | 
				
			||||||
    PoolUpdateView, PoolUpdateTeamsView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, \
 | 
					    PoolUpdateView, PoolUpdateTeamsView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, \
 | 
				
			||||||
    TeamUpdateView, TournamentCreateView, TournamentDetailView, TournamentListView, TournamentUpdateView, \
 | 
					    TeamUpdateView, TournamentCreateView, TournamentDetailView, TournamentListView, TournamentUpdateView, \
 | 
				
			||||||
    SolutionUploadView
 | 
					    SolutionUploadView
 | 
				
			||||||
@@ -33,5 +34,8 @@ urlpatterns = [
 | 
				
			|||||||
    path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
 | 
					    path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
 | 
				
			||||||
    path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
 | 
					    path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
 | 
				
			||||||
    path("pools/<int:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"),
 | 
					    path("pools/<int:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"),
 | 
				
			||||||
 | 
					    path("pools/passages/add/<int:pk>/", PassageCreateView.as_view(), name="passage_create"),
 | 
				
			||||||
 | 
					    path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),
 | 
				
			||||||
 | 
					    path("pools/passages/<int:pk>/update/", PassageUpdateView.as_view(), name="passage_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")
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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, PoolForm, PoolTeamsForm, RequestValidationForm, SolutionForm, \
 | 
					from .forms import JoinTeamForm, ParticipationForm, PassageForm, PoolForm, PoolTeamsForm, RequestValidationForm, \
 | 
				
			||||||
    TeamForm, TournamentForm, ValidateParticipationForm
 | 
					    SolutionForm, TeamForm, TournamentForm, ValidateParticipationForm
 | 
				
			||||||
from .models import Participation, Team, Tournament, Solution, Pool
 | 
					from .models import Participation, Passage, Pool, Team, Tournament, Solution
 | 
				
			||||||
from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable
 | 
					from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -487,3 +487,33 @@ class PoolUpdateView(AdminMixin, UpdateView):
 | 
				
			|||||||
class PoolUpdateTeamsView(AdminMixin, UpdateView):
 | 
					class PoolUpdateTeamsView(AdminMixin, UpdateView):
 | 
				
			||||||
    model = Pool
 | 
					    model = Pool
 | 
				
			||||||
    form_class = PoolTeamsForm
 | 
					    form_class = PoolTeamsForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PassageCreateView(AdminMixin, CreateView):
 | 
				
			||||||
 | 
					    model = Passage
 | 
				
			||||||
 | 
					    form_class = PassageForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def dispatch(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        qs = Pool.objects.filter(pk=self.kwargs["pk"])
 | 
				
			||||||
 | 
					        if not qs.exists():
 | 
				
			||||||
 | 
					            raise Http404
 | 
				
			||||||
 | 
					        self.pool = qs.get()
 | 
				
			||||||
 | 
					        return super().dispatch(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_form(self, form_class=None):
 | 
				
			||||||
 | 
					        form = super().get_form(form_class)
 | 
				
			||||||
 | 
					        form.instance.pool = self.pool
 | 
				
			||||||
 | 
					        form.fields["defender"].queryset = self.pool.participations.all()
 | 
				
			||||||
 | 
					        form.fields["opponent"].queryset = self.pool.participations.all()
 | 
				
			||||||
 | 
					        form.fields["reporter"].queryset = self.pool.participations.all()
 | 
				
			||||||
 | 
					        return form
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PassageDetailView(AdminMixin, DetailView):
 | 
				
			||||||
 | 
					    model = Passage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PassageUpdateView(AdminMixin, UpdateView):
 | 
				
			||||||
 | 
					    model = Passage
 | 
				
			||||||
 | 
					    form_class = PassageForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user