Add duplication check for contest edit in group
This commit is contained in:
parent
0da2098bbe
commit
97d0239963
6 changed files with 64 additions and 25 deletions
|
@ -538,9 +538,37 @@ class ContestProblemForm(ModelForm):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ContestProblemModelFormSet(BaseModelFormSet):
|
||||||
|
def is_valid(self):
|
||||||
|
valid = super().is_valid()
|
||||||
|
|
||||||
|
if not valid:
|
||||||
|
return valid
|
||||||
|
|
||||||
|
problems = set()
|
||||||
|
duplicates = []
|
||||||
|
|
||||||
|
for form in self.forms:
|
||||||
|
if form.cleaned_data and not form.cleaned_data.get("DELETE", False):
|
||||||
|
problem = form.cleaned_data.get("problem")
|
||||||
|
if problem in problems:
|
||||||
|
duplicates.append(problem)
|
||||||
|
else:
|
||||||
|
problems.add(problem)
|
||||||
|
|
||||||
|
if duplicates:
|
||||||
|
for form in self.forms:
|
||||||
|
problem = form.cleaned_data.get("problem")
|
||||||
|
if problem in duplicates:
|
||||||
|
form.add_error("problem", _("This problem is duplicated."))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ContestProblemFormSet(
|
class ContestProblemFormSet(
|
||||||
formset_factory(
|
formset_factory(
|
||||||
ContestProblemForm, formset=BaseModelFormSet, extra=6, can_delete=True
|
ContestProblemForm, formset=ContestProblemModelFormSet, extra=6, can_delete=True
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
model = ContestProblem
|
model = ContestProblem
|
||||||
|
|
|
@ -926,8 +926,12 @@ class EditOrganizationContest(
|
||||||
super().post(request, *args, **kwargs)
|
super().post(request, *args, **kwargs)
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
reverse(
|
reverse(
|
||||||
"organization_contests",
|
"organization_contest_edit",
|
||||||
args=(self.organization_id, self.organization.slug),
|
args=(
|
||||||
|
self.organization_id,
|
||||||
|
self.organization.slug,
|
||||||
|
self.contest.key,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: lqdoj2\n"
|
"Project-Id-Version: lqdoj2\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-08-26 03:42+0700\n"
|
"POT-Creation-Date: 2023-08-26 05:31+0700\n"
|
||||||
"PO-Revision-Date: 2021-07-20 03:44\n"
|
"PO-Revision-Date: 2021-07-20 03:44\n"
|
||||||
"Last-Translator: Icyene\n"
|
"Last-Translator: Icyene\n"
|
||||||
"Language-Team: Vietnamese\n"
|
"Language-Team: Vietnamese\n"
|
||||||
|
@ -555,6 +555,10 @@ msgstr ""
|
||||||
msgid "You don't have permission in this group."
|
msgid "You don't have permission in this group."
|
||||||
msgstr "Bạn không có quyền chấm lại bài."
|
msgstr "Bạn không có quyền chấm lại bài."
|
||||||
|
|
||||||
|
#: judge/forms.py:563
|
||||||
|
msgid "This problem is duplicated."
|
||||||
|
msgstr "Bài này bị lặp"
|
||||||
|
|
||||||
#: judge/jinja2/datetime.py:26 templates/blog/blog.html:28
|
#: judge/jinja2/datetime.py:26 templates/blog/blog.html:28
|
||||||
#: templates/blog/dashboard.html:21
|
#: templates/blog/dashboard.html:21
|
||||||
msgid "N j, Y, g:i a"
|
msgid "N j, Y, g:i a"
|
||||||
|
@ -2883,19 +2887,19 @@ msgstr "Thay đổi Email"
|
||||||
msgid "Change Email"
|
msgid "Change Email"
|
||||||
msgstr "Thay đổi Email"
|
msgstr "Thay đổi Email"
|
||||||
|
|
||||||
#: judge/views/email.py:65 templates/user/edit-profile.html:120
|
#: judge/views/email.py:71 templates/user/edit-profile.html:120
|
||||||
msgid "Change email"
|
msgid "Change email"
|
||||||
msgstr "Thay đổi email"
|
msgstr "Thay đổi email"
|
||||||
|
|
||||||
#: judge/views/email.py:89
|
#: judge/views/email.py:94
|
||||||
msgid "Success"
|
msgid "Success"
|
||||||
msgstr "Thành công"
|
msgstr "Thành công"
|
||||||
|
|
||||||
#: judge/views/email.py:93
|
#: judge/views/email.py:98
|
||||||
msgid "Invalid"
|
msgid "Invalid"
|
||||||
msgstr "Không hợp lệ"
|
msgstr "Không hợp lệ"
|
||||||
|
|
||||||
#: judge/views/email.py:102
|
#: judge/views/email.py:107
|
||||||
msgid "Email change pending"
|
msgid "Email change pending"
|
||||||
msgstr "Yêu cầu thay đổi email đang đợi xác thực."
|
msgstr "Yêu cầu thay đổi email đang đợi xác thực."
|
||||||
|
|
||||||
|
@ -4426,8 +4430,8 @@ msgstr "Hoạt động"
|
||||||
|
|
||||||
#: templates/organization/blog/edit.html:36
|
#: templates/organization/blog/edit.html:36
|
||||||
#: templates/organization/contest/add.html:36
|
#: templates/organization/contest/add.html:36
|
||||||
#: templates/organization/contest/edit.html:87
|
#: templates/organization/contest/edit.html:86
|
||||||
#: templates/organization/form.html:24
|
#: templates/organization/form.html:23
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Lưu"
|
msgstr "Lưu"
|
||||||
|
|
||||||
|
@ -4441,12 +4445,15 @@ msgid "Author"
|
||||||
msgstr "Tác giả"
|
msgstr "Tác giả"
|
||||||
|
|
||||||
#: templates/organization/blog/pending.html:14
|
#: templates/organization/blog/pending.html:14
|
||||||
#, fuzzy
|
|
||||||
#| msgid "posted time"
|
|
||||||
msgid "Post time"
|
msgid "Post time"
|
||||||
msgstr "thời gian đăng"
|
msgstr "Thời gian đăng"
|
||||||
|
|
||||||
#: templates/organization/contest/edit.html:61
|
#: templates/organization/contest/edit.html:40
|
||||||
|
#: templates/organization/form.html:6
|
||||||
|
msgid "Please fix below errors"
|
||||||
|
msgstr "Vui lòng sửa các lỗi bên dưới"
|
||||||
|
|
||||||
|
#: templates/organization/contest/edit.html:60
|
||||||
msgid "If you run out of rows, click Save"
|
msgid "If you run out of rows, click Save"
|
||||||
msgstr "Ấn nút lưu lại nếu cần thêm hàng"
|
msgstr "Ấn nút lưu lại nếu cần thêm hàng"
|
||||||
|
|
||||||
|
|
|
@ -606,6 +606,14 @@ ul.select2-selection__rendered {
|
||||||
background: gray;
|
background: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.errorlist {
|
||||||
|
margin: 0px;
|
||||||
|
text-align: right;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
.registration-form {
|
.registration-form {
|
||||||
.sortedm2m-container, .sortedm2m-container p.selector-filter {
|
.sortedm2m-container, .sortedm2m-container p.selector-filter {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@ -682,12 +690,6 @@ ul.select2-selection__rendered {
|
||||||
width: 450px;
|
width: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.errorlist {
|
|
||||||
margin: 0px;
|
|
||||||
text-align: right;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-textfield {
|
.full-textfield {
|
||||||
padding-top: 0.5em;
|
padding-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,10 @@
|
||||||
{% block middle_content %}
|
{% block middle_content %}
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if form.errors %}
|
{% if form.errors or problems_form.errors %}
|
||||||
<div class="alert alert-danger alert-dismissable">
|
<div class="alert alert-danger alert-dismissable">
|
||||||
<a href="#" class="close">x</a>
|
<a href="#" class="close">x</a>
|
||||||
{{ form.non_field_errors() }}
|
{{_("Please fix below errors")}}
|
||||||
{{ form.errors }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
{% if form.errors %}
|
{% if form.errors %}
|
||||||
<div class="alert alert-danger alert-dismissable">
|
<div class="alert alert-danger alert-dismissable">
|
||||||
<a href="#" class="close">x</a>
|
<a href="#" class="close">x</a>
|
||||||
{{ form.non_field_errors() }}
|
{{ _("Please fix below errors") }}
|
||||||
{{ form.errors }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
|
|
Loading…
Reference in a new issue