Add validation code
This commit is contained in:
parent
0ea822f7a0
commit
adb7c182d8
2 changed files with 40 additions and 36 deletions
|
@ -24,6 +24,7 @@ from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django.utils.datastructures import MultiValueDictKeyError
|
||||||
from django.views.decorators.http import require_POST
|
from django.views.decorators.http import require_POST
|
||||||
from django.views.generic import DetailView, UpdateView, View
|
from django.views.generic import DetailView, UpdateView, View
|
||||||
from django.views.generic.base import TemplateResponseMixin
|
from django.views.generic.base import TemplateResponseMixin
|
||||||
|
@ -130,7 +131,7 @@ def get_comments(request, limit=10):
|
||||||
try:
|
try:
|
||||||
comment_id = int(request.GET["id"])
|
comment_id = int(request.GET["id"])
|
||||||
parent_none = int(request.GET["parent_none"])
|
parent_none = int(request.GET["parent_none"])
|
||||||
except ValueError:
|
except (ValueError, MultiValueDictKeyError):
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
else:
|
else:
|
||||||
if comment_id and not Comment.objects.filter(id=comment_id).exists():
|
if comment_id and not Comment.objects.filter(id=comment_id).exists():
|
||||||
|
@ -138,7 +139,10 @@ def get_comments(request, limit=10):
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
if "offset" in request.GET:
|
if "offset" in request.GET:
|
||||||
offset = int(request.GET["offset"])
|
try:
|
||||||
|
offset = int(request.GET["offset"])
|
||||||
|
except ValueError:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
target_comment = -1
|
target_comment = -1
|
||||||
if "target_comment" in request.GET:
|
if "target_comment" in request.GET:
|
||||||
|
|
|
@ -51,6 +51,7 @@ from judge.utils.infinite_paginator import InfinitePaginationMixin
|
||||||
from judge.utils.views import TitleMixin
|
from judge.utils.views import TitleMixin
|
||||||
from judge.utils.timedelta import nice_repr
|
from judge.utils.timedelta import nice_repr
|
||||||
from judge.views.contests import ContestMixin
|
from judge.views.contests import ContestMixin
|
||||||
|
from judge.caching import cache_wrapper
|
||||||
|
|
||||||
|
|
||||||
def submission_related(queryset):
|
def submission_related(queryset):
|
||||||
|
@ -380,17 +381,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.selected_languages:
|
if self.selected_languages:
|
||||||
# Note (DMOJ): MariaDB can't optimize this subquery for some insane, unknown reason,
|
queryset = queryset.filter(language__in=self.selected_languages)
|
||||||
# so we are forcing an eager evaluation to get the IDs right here.
|
|
||||||
# Otherwise, with multiple language filters, MariaDB refuses to use an index
|
|
||||||
# (or runs the subquery for every submission, which is even more horrifying to think about).
|
|
||||||
queryset = queryset.filter(
|
|
||||||
language__in=list(
|
|
||||||
Language.objects.filter(
|
|
||||||
key__in=self.selected_languages
|
|
||||||
).values_list("id", flat=True)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if self.selected_statuses:
|
if self.selected_statuses:
|
||||||
submission_results = [i for i, _ in Submission.RESULT]
|
submission_results = [i for i, _ in Submission.RESULT]
|
||||||
if self.selected_statuses[0] in submission_results:
|
if self.selected_statuses[0] in submission_results:
|
||||||
|
@ -461,7 +452,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
context["show_problem"] = self.show_problem
|
context["show_problem"] = self.show_problem
|
||||||
context["profile"] = self.request.profile
|
context["profile"] = self.request.profile
|
||||||
context["all_languages"] = Language.objects.all().values_list("key", "name")
|
context["all_languages"] = Language.objects.all().values_list("key", "name")
|
||||||
context["selected_languages"] = self.selected_languages
|
context["selected_languages"] = self.selected_languages_key
|
||||||
context["all_statuses"] = self.get_searchable_status_codes()
|
context["all_statuses"] = self.get_searchable_status_codes()
|
||||||
context["selected_statuses"] = self.selected_statuses
|
context["selected_statuses"] = self.selected_statuses
|
||||||
|
|
||||||
|
@ -501,6 +492,18 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
||||||
self.selected_languages = request.GET.getlist("language")
|
self.selected_languages = request.GET.getlist("language")
|
||||||
self.selected_statuses = request.GET.getlist("status")
|
self.selected_statuses = request.GET.getlist("status")
|
||||||
|
|
||||||
|
if self.selected_languages:
|
||||||
|
languages = Language.objects.filter(key__in=self.selected_languages).values(
|
||||||
|
"id", "key"
|
||||||
|
)
|
||||||
|
self.selected_languages = [i["id"] for i in languages]
|
||||||
|
self.selected_languages_key = [i["key"] for i in languages]
|
||||||
|
if self.selected_statuses:
|
||||||
|
allowed_statuses = [i for i, _ in Submission.RESULT + Submission.STATUS]
|
||||||
|
self.selected_statuses = [
|
||||||
|
i for i in self.selected_statuses if i in allowed_statuses
|
||||||
|
]
|
||||||
|
|
||||||
if self.in_contest and self.contest.is_editable_by(self.request.user):
|
if self.in_contest and self.contest.is_editable_by(self.request.user):
|
||||||
self.include_frozen = True
|
self.include_frozen = True
|
||||||
|
|
||||||
|
@ -795,28 +798,9 @@ class AllSubmissions(InfinitePaginationMixin, GeneralSubmissions):
|
||||||
if self.request.organization or self.in_contest:
|
if self.request.organization or self.in_contest:
|
||||||
return super(AllSubmissions, self)._get_result_data()
|
return super(AllSubmissions, self)._get_result_data()
|
||||||
|
|
||||||
key = "global_submission_result_data"
|
return _get_global_submission_result_data(
|
||||||
if self.selected_statuses:
|
self.selected_statuses, self.selected_languages
|
||||||
key += ":" + ",".join(self.selected_statuses)
|
)
|
||||||
if self.selected_languages:
|
|
||||||
key += ":" + ",".join(self.selected_languages)
|
|
||||||
result = cache.get(key)
|
|
||||||
if result:
|
|
||||||
return result
|
|
||||||
queryset = Submission.objects
|
|
||||||
if self.selected_languages:
|
|
||||||
queryset = queryset.filter(
|
|
||||||
language__in=Language.objects.filter(key__in=self.selected_languages)
|
|
||||||
)
|
|
||||||
if self.selected_statuses:
|
|
||||||
submission_results = [i for i, _ in Submission.RESULT]
|
|
||||||
if self.selected_statuses[0] in submission_results:
|
|
||||||
queryset = queryset.filter(result__in=self.selected_statuses)
|
|
||||||
else:
|
|
||||||
queryset = queryset.filter(status__in=self.selected_statuses)
|
|
||||||
result = get_result_data(queryset)
|
|
||||||
cache.set(key, result, self.stats_update_interval)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class ForceContestMixin(object):
|
class ForceContestMixin(object):
|
||||||
|
@ -1071,3 +1055,19 @@ class SubmissionSourceFileView(View):
|
||||||
response["Content-Type"] = "application/octet-stream"
|
response["Content-Type"] = "application/octet-stream"
|
||||||
response["Content-Disposition"] = "attachment; filename=%s" % (filename,)
|
response["Content-Disposition"] = "attachment; filename=%s" % (filename,)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@cache_wrapper(prefix="gsrd", timeout=3600, expected_type=dict)
|
||||||
|
def _get_global_submission_result_data(statuses, languages):
|
||||||
|
queryset = Submission.objects
|
||||||
|
if languages:
|
||||||
|
queryset = queryset.filter(
|
||||||
|
language__in=Language.objects.filter(id__in=languages)
|
||||||
|
)
|
||||||
|
if statuses:
|
||||||
|
submission_results = [i for i, _ in Submission.RESULT]
|
||||||
|
if statuses[0] in submission_results:
|
||||||
|
queryset = queryset.filter(result__in=statuses)
|
||||||
|
else:
|
||||||
|
queryset = queryset.filter(status__in=statuses)
|
||||||
|
return get_result_data(queryset)
|
||||||
|
|
Loading…
Reference in a new issue