Skip to content

Commit

Permalink
Adds a phase create form (#1603)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmsmkn committed Nov 23, 2020
1 parent 6383358 commit a314442
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 5 deletions.
4 changes: 4 additions & 0 deletions app/grandchallenge/core/templates/challenge.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ <h6 class="dropdown-header">{{ phase.title }} Evaluation</h6>
</a>
{% endfor %}
<hr>
<a class="dropdown-item"
href="{% url 'evaluation:phase-create' challenge_short_name=challenge.short_name %}">
<i class="fas fa-plus fa-fw"></i>&nbsp;Add a new Phase
</a>
<a class="dropdown-item"
href="{% url 'evaluation:method-list' challenge_short_name=challenge.short_name %}">
Methods
Expand Down
28 changes: 27 additions & 1 deletion app/grandchallenge/evaluation/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from grandchallenge.jqfileupload.widgets.uploader import UploadedAjaxFileList
from grandchallenge.subdomains.utils import reverse_lazy

phase_options = ("title",)

submission_options = (
"submission_page_html",
"daily_submission_limit",
Expand Down Expand Up @@ -58,12 +60,35 @@
)


class PhaseForm(forms.ModelForm):
class PhaseTitleMixin:
def __init__(self, *args, challenge, **kwargs):
self.challenge = challenge
super().__init__(*args, **kwargs)

def clean_title(self):
title = self.cleaned_data["title"]

if self.challenge.phase_set.filter(title=title).exists():
raise ValidationError(
"This challenge already has a phase with this title"
)

return title


class PhaseCreateForm(PhaseTitleMixin, SaveFormInitMixin, forms.ModelForm):
class Meta:
model = Phase
fields = ("title",)


class PhaseUpdateForm(PhaseTitleMixin, forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.layout = Layout(
TabHolder(
Tab("Phase", *phase_options),
Tab("Submission", *submission_options),
Tab("Scoring", *scoring_options),
Tab("Leaderboard", *leaderboard_options),
Expand All @@ -75,6 +100,7 @@ def __init__(self, *args, **kwargs):
class Meta:
model = Phase
fields = (
*phase_options,
*submission_options,
*scoring_options,
*leaderboard_options,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<li class="breadcrumb-item"><a
href="{{ challenge.get_absolute_url }}">{% firstof challenge.title challenge.short_name %}</a></li>
<li class="breadcrumb-item active"
aria-current="page">{{ object.title }} Evaluation Settings</li>
aria-current="page">{{ object.title }} Add a New Phase</li>
</ol>
{% endblock %}

Expand All @@ -19,7 +19,14 @@

{% block content %}

<h2>{{ object.title }} Evaluation Settings</h2>
<h2>{% if object %}Update {{ object.title }} Phase{% else %}Add a New Phase{% endif %}</h2>

{% if not object %}
<p>
Use this form to create a new phase for your challenge with a separate evaluation method.
For instance, you could have a training and test phase, or have a phase for each task.
</p>
{% endif %}

{% crispy form %}

Expand Down
2 changes: 2 additions & 0 deletions app/grandchallenge/evaluation/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
MethodDetail,
MethodList,
ObservableDetail,
PhaseCreate,
PhaseUpdate,
SubmissionCreate,
SubmissionDetail,
Expand All @@ -24,6 +25,7 @@
path("<uuid:pk>/", EvaluationDetail.as_view(), name="detail"),
# UUID should be matched before slugs
path("<uuid:pk>/update/", EvaluationUpdate.as_view(), name="update"),
path("phase/create/", PhaseCreate.as_view(), name="phase-create"),
path(
"<slug>/leaderboard/", LeaderboardDetail.as_view(), name="leaderboard"
),
Expand Down
36 changes: 34 additions & 2 deletions app/grandchallenge/evaluation/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
from grandchallenge.evaluation.forms import (
LegacySubmissionForm,
MethodForm,
PhaseForm,
PhaseCreateForm,
PhaseUpdateForm,
SubmissionForm,
)
from grandchallenge.evaluation.models import (
Expand All @@ -46,13 +47,39 @@
from grandchallenge.teams.models import Team


class PhaseCreate(
LoginRequiredMixin,
ObjectPermissionRequiredMixin,
SuccessMessageMixin,
CreateView,
):
model = Phase
form_class = PhaseCreateForm
success_message = "Phase successfully created"
permission_required = "change_challenge"
raise_exception = True
login_url = reverse_lazy("userena_signin")

def get_permission_object(self):
return self.request.challenge

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update({"challenge": self.request.challenge})
return kwargs

def form_valid(self, form):
form.instance.challenge = self.request.challenge
return super().form_valid(form)


class PhaseUpdate(
LoginRequiredMixin,
ObjectPermissionRequiredMixin,
SuccessMessageMixin,
UpdateView,
):
form_class = PhaseForm
form_class = PhaseUpdateForm
success_message = "Configuration successfully updated"
permission_required = "change_phase"
raise_exception = True
Expand All @@ -63,6 +90,11 @@ def get_object(self, queryset=None):
challenge=self.request.challenge, slug=self.kwargs["slug"]
)

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update({"challenge": self.request.challenge})
return kwargs

def get_success_url(self):
return reverse(
"evaluation:leaderboard",
Expand Down
7 changes: 7 additions & 0 deletions app/tests/evaluation_tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def test_login_redirect(self, client):
e = EvaluationFactory()

for view_name, kwargs in [
("phase-create", {}),
("phase-update", {"slug": e.submission.phase.slug}),
("method-create", {}),
("method-list", {}),
Expand Down Expand Up @@ -77,6 +78,12 @@ def test_permission_required_views(self, client):
u = UserFactory()

for view_name, kwargs, permission, obj in [
(
"phase-create",
{},
"change_challenge",
e.submission.phase.challenge,
),
(
"phase-update",
{"slug": e.submission.phase.slug},
Expand Down

0 comments on commit a314442

Please sign in to comment.