精简 Problem 模型:移除 rule_type / total_score / io_mode
系统只用 ACM 模式且题目固定标准 IO,这三列已无实际用途: - rule_type / total_score:OI 专用,删除后 judge/dispatcher 的 OI 分支全部塌缩为 ACM - io_mode:判题改为固定发送 Standard IO 常量;languages.py 的 seccomp_rule 保留 dict 形态但改用字面量 key,不改判题机 wire 契约 - prompt 字段保留(预留给未来 AI 分析) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ from account.models import User
|
|||||||
from conf.models import JudgeServer
|
from conf.models import JudgeServer
|
||||||
from contest.models import ACMContestRank
|
from contest.models import ACMContestRank
|
||||||
from options.options import SysOptions
|
from options.options import SysOptions
|
||||||
from problem.models import Problem, ProblemRuleType
|
from problem.models import Problem
|
||||||
from problem.utils import parse_problem_template
|
from problem.utils import parse_problem_template
|
||||||
from submission.models import JudgeStatus, Submission, is_accepted
|
from submission.models import JudgeStatus, Submission, is_accepted
|
||||||
from utils.cache import cache
|
from utils.cache import cache
|
||||||
@@ -114,22 +114,6 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
self.submission.statistic_info["time_cost"] = max([x["cpu_time"] for x in resp_data])
|
self.submission.statistic_info["time_cost"] = max([x["cpu_time"] for x in resp_data])
|
||||||
self.submission.statistic_info["memory_cost"] = max([x["memory"] for x in resp_data])
|
self.submission.statistic_info["memory_cost"] = max([x["memory"] for x in resp_data])
|
||||||
|
|
||||||
# sum up the score in OI mode
|
|
||||||
if self.problem.rule_type == ProblemRuleType.OI:
|
|
||||||
score = 0
|
|
||||||
try:
|
|
||||||
for i in range(len(resp_data)):
|
|
||||||
if resp_data[i]["result"] == JudgeStatus.ACCEPTED:
|
|
||||||
resp_data[i]["score"] = self.problem.test_case_score[i]["score"]
|
|
||||||
score += resp_data[i]["score"]
|
|
||||||
else:
|
|
||||||
resp_data[i]["score"] = 0
|
|
||||||
except IndexError:
|
|
||||||
logger.error(f"Index Error raised when summing up the score in problem {self.problem.id}")
|
|
||||||
self.submission.statistic_info["score"] = 0
|
|
||||||
return
|
|
||||||
self.submission.statistic_info["score"] = score
|
|
||||||
|
|
||||||
def judge(self):
|
def judge(self):
|
||||||
language = self.submission.language
|
language = self.submission.language
|
||||||
sub_config = list(filter(lambda item: language == item["name"], SysOptions.languages))[0]
|
sub_config = list(filter(lambda item: language == item["name"], SysOptions.languages))[0]
|
||||||
@@ -147,7 +131,7 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
"max_memory": 1024 * 1024 * self.problem.memory_limit,
|
"max_memory": 1024 * 1024 * self.problem.memory_limit,
|
||||||
"test_case_id": self.problem.test_case_id,
|
"test_case_id": self.problem.test_case_id,
|
||||||
"output": False,
|
"output": False,
|
||||||
"io_mode": self.problem.io_mode,
|
"io_mode": {"io_mode": "Standard IO", "input": "input.txt", "output": "output.txt"},
|
||||||
}
|
}
|
||||||
|
|
||||||
with ChooseJudgeServer() as server:
|
with ChooseJudgeServer() as server:
|
||||||
@@ -188,14 +172,11 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
self.submission.info = resp
|
self.submission.info = resp
|
||||||
self._compute_statistic_info(resp["data"])
|
self._compute_statistic_info(resp["data"])
|
||||||
error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"]))
|
error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"]))
|
||||||
# ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态
|
# 多个测试点全部正确则AC,否则取第一个错误的测试点的状态
|
||||||
# OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确
|
|
||||||
if not error_test_case:
|
if not error_test_case:
|
||||||
self.submission.result = JudgeStatus.ACCEPTED
|
self.submission.result = JudgeStatus.ACCEPTED
|
||||||
elif self.problem.rule_type == ProblemRuleType.ACM or len(error_test_case) == len(resp["data"]):
|
|
||||||
self.submission.result = error_test_case[0]["result"]
|
|
||||||
else:
|
else:
|
||||||
self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED
|
self.submission.result = error_test_case[0]["result"]
|
||||||
|
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||||
ast_rules = self.problem.ast_rules
|
ast_rules = self.problem.ast_rules
|
||||||
@@ -252,7 +233,6 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
problem.save(update_fields=["accepted_number", "statistic_info"])
|
problem.save(update_fields=["accepted_number", "statistic_info"])
|
||||||
|
|
||||||
profile = User.objects.select_for_update().get(id=self.submission.user_id).userprofile
|
profile = User.objects.select_for_update().get(id=self.submission.user_id).userprofile
|
||||||
if problem.rule_type == ProblemRuleType.ACM:
|
|
||||||
acm_problems_status = profile.acm_problems_status.get("problems", {})
|
acm_problems_status = profile.acm_problems_status.get("problems", {})
|
||||||
if not is_accepted(acm_problems_status[problem_id]["status"]):
|
if not is_accepted(acm_problems_status[problem_id]["status"]):
|
||||||
acm_problems_status[problem_id]["status"] = JudgeStatus.ACCEPTED if is_accepted(self.submission.result) else self.submission.result
|
acm_problems_status[problem_id]["status"] = JudgeStatus.ACCEPTED if is_accepted(self.submission.result) else self.submission.result
|
||||||
@@ -261,19 +241,6 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
profile.acm_problems_status["problems"] = acm_problems_status
|
profile.acm_problems_status["problems"] = acm_problems_status
|
||||||
profile.save(update_fields=["accepted_number", "acm_problems_status"])
|
profile.save(update_fields=["accepted_number", "acm_problems_status"])
|
||||||
|
|
||||||
else:
|
|
||||||
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
|
||||||
score = self.submission.statistic_info["score"]
|
|
||||||
if not is_accepted(oi_problems_status[problem_id]["status"]):
|
|
||||||
# minus last time score, add this tim score
|
|
||||||
profile.add_score(this_time_score=score, last_time_score=oi_problems_status[problem_id]["score"])
|
|
||||||
oi_problems_status[problem_id]["score"] = score
|
|
||||||
oi_problems_status[problem_id]["status"] = JudgeStatus.ACCEPTED if is_accepted(self.submission.result) else self.submission.result
|
|
||||||
if is_accepted(self.submission.result):
|
|
||||||
profile.accepted_number += 1
|
|
||||||
profile.oi_problems_status["problems"] = oi_problems_status
|
|
||||||
profile.save(update_fields=["accepted_number", "oi_problems_status"])
|
|
||||||
|
|
||||||
def update_problem_status(self):
|
def update_problem_status(self):
|
||||||
result = str(self.submission.result)
|
result = str(self.submission.result)
|
||||||
problem_id = str(self.problem.id)
|
problem_id = str(self.problem.id)
|
||||||
@@ -292,7 +259,6 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
user_profile = user.userprofile
|
user_profile = user.userprofile
|
||||||
user_profile.submission_number = F("submission_number") + 1
|
user_profile.submission_number = F("submission_number") + 1
|
||||||
profile_status = JudgeStatus.ACCEPTED if is_accepted(self.submission.result) else self.submission.result
|
profile_status = JudgeStatus.ACCEPTED if is_accepted(self.submission.result) else self.submission.result
|
||||||
if problem.rule_type == ProblemRuleType.ACM:
|
|
||||||
acm_problems_status = user_profile.acm_problems_status.get("problems", {})
|
acm_problems_status = user_profile.acm_problems_status.get("problems", {})
|
||||||
if problem_id not in acm_problems_status:
|
if problem_id not in acm_problems_status:
|
||||||
acm_problems_status[problem_id] = {"status": profile_status, "_id": self.problem._id}
|
acm_problems_status[problem_id] = {"status": profile_status, "_id": self.problem._id}
|
||||||
@@ -305,24 +271,6 @@ class JudgeDispatcher(DispatcherBase):
|
|||||||
user_profile.acm_problems_status["problems"] = acm_problems_status
|
user_profile.acm_problems_status["problems"] = acm_problems_status
|
||||||
user_profile.save(update_fields=["submission_number", "accepted_number", "acm_problems_status"])
|
user_profile.save(update_fields=["submission_number", "accepted_number", "acm_problems_status"])
|
||||||
|
|
||||||
else:
|
|
||||||
oi_problems_status = user_profile.oi_problems_status.get("problems", {})
|
|
||||||
score = self.submission.statistic_info["score"]
|
|
||||||
if problem_id not in oi_problems_status:
|
|
||||||
user_profile.add_score(score)
|
|
||||||
oi_problems_status[problem_id] = {"status": profile_status, "_id": self.problem._id, "score": score}
|
|
||||||
if is_accepted(self.submission.result):
|
|
||||||
user_profile.accepted_number += 1
|
|
||||||
elif not is_accepted(oi_problems_status[problem_id]["status"]):
|
|
||||||
# minus last time score, add this time score
|
|
||||||
user_profile.add_score(this_time_score=score, last_time_score=oi_problems_status[problem_id]["score"])
|
|
||||||
oi_problems_status[problem_id]["score"] = score
|
|
||||||
oi_problems_status[problem_id]["status"] = profile_status
|
|
||||||
if is_accepted(self.submission.result):
|
|
||||||
user_profile.accepted_number += 1
|
|
||||||
user_profile.oi_problems_status["problems"] = oi_problems_status
|
|
||||||
user_profile.save(update_fields=["submission_number", "accepted_number", "oi_problems_status"])
|
|
||||||
|
|
||||||
def update_contest_problem_status(self):
|
def update_contest_problem_status(self):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
user = User.objects.select_for_update().get(id=self.submission.user_id)
|
user = User.objects.select_for_update().get(id=self.submission.user_id)
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
from problem.models import ProblemIOMode
|
|
||||||
|
|
||||||
default_env = ["LANG=en_US.UTF-8", "LANGUAGE=en_US:en", "LC_ALL=en_US.UTF-8"]
|
default_env = ["LANG=en_US.UTF-8", "LANGUAGE=en_US:en", "LC_ALL=en_US.UTF-8"]
|
||||||
|
|
||||||
_c_lang_config = {
|
_c_lang_config = {
|
||||||
@@ -27,7 +25,7 @@ int main() {
|
|||||||
"max_memory": 256 * 1024 * 1024,
|
"max_memory": 256 * 1024 * 1024,
|
||||||
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c17 {src_path} -lm -o {exe_path}",
|
"compile_command": "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c17 {src_path} -lm -o {exe_path}",
|
||||||
},
|
},
|
||||||
"run": {"command": "{exe_path}", "seccomp_rule": {ProblemIOMode.STANDARD: "c_cpp", ProblemIOMode.FILE: "c_cpp_file_io"}, "env": default_env},
|
"run": {"command": "{exe_path}", "seccomp_rule": {"Standard IO": "c_cpp", "File IO": "c_cpp_file_io"}, "env": default_env},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -56,7 +54,7 @@ int main() {
|
|||||||
"max_memory": 1024 * 1024 * 1024,
|
"max_memory": 1024 * 1024 * 1024,
|
||||||
"compile_command": "/usr/bin/g++ -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c++20 {src_path} -lm -o {exe_path}",
|
"compile_command": "/usr/bin/g++ -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c++20 {src_path} -lm -o {exe_path}",
|
||||||
},
|
},
|
||||||
"run": {"command": "{exe_path}", "seccomp_rule": {ProblemIOMode.STANDARD: "c_cpp", ProblemIOMode.FILE: "c_cpp_file_io"}, "env": default_env},
|
"run": {"command": "{exe_path}", "seccomp_rule": {"Standard IO": "c_cpp", "File IO": "c_cpp_file_io"}, "env": default_env},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class SQLJudgeDispatcher(JudgeDispatcher):
|
|||||||
raise SQLProblemConfigError("测试点不是 SQL 类型,请重新上传 SQL 测试点压缩包")
|
raise SQLProblemConfigError("测试点不是 SQL 类型,请重新上传 SQL 测试点压缩包")
|
||||||
|
|
||||||
init_scripts = []
|
init_scripts = []
|
||||||
# 按 "1","2",… 自然序遍历,保证与 test_case_score 的下标对应(OI 计分依赖顺序)
|
# 按 "1","2",… 自然序遍历,保证测试点顺序稳定
|
||||||
for key in sorted(info["test_cases"].keys(), key=natural_sort_key):
|
for key in sorted(info["test_cases"].keys(), key=natural_sort_key):
|
||||||
input_name = info["test_cases"][key]["input_name"]
|
input_name = info["test_cases"][key]["input_name"]
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 5.2.3 on 2025-06-14 08:51
|
# Generated by Django 5.2.3 on 2025-06-14 08:51
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import problem.models
|
|
||||||
import utils.models
|
import utils.models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
@@ -47,7 +46,7 @@ class Migration(migrations.Migration):
|
|||||||
('last_update_time', models.DateTimeField(auto_now=True, null=True)),
|
('last_update_time', models.DateTimeField(auto_now=True, null=True)),
|
||||||
('time_limit', models.IntegerField()),
|
('time_limit', models.IntegerField()),
|
||||||
('memory_limit', models.IntegerField()),
|
('memory_limit', models.IntegerField()),
|
||||||
('io_mode', models.JSONField(default=problem.models._default_io_mode)),
|
('io_mode', models.JSONField(default=dict)),
|
||||||
('spj', models.BooleanField(default=False)),
|
('spj', models.BooleanField(default=False)),
|
||||||
('spj_language', models.TextField(null=True)),
|
('spj_language', models.TextField(null=True)),
|
||||||
('spj_code', models.TextField(null=True)),
|
('spj_code', models.TextField(null=True)),
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 6.0.4 on 2026-07-04 17:27
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('problem', '0012_problem_sql_display'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='problem',
|
||||||
|
name='io_mode',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='problem',
|
||||||
|
name='rule_type',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='problem',
|
||||||
|
name='total_score',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -13,24 +13,6 @@ class ProblemTag(models.Model):
|
|||||||
db_table = "problem_tag"
|
db_table = "problem_tag"
|
||||||
|
|
||||||
|
|
||||||
class ProblemRuleType(models.TextChoices):
|
|
||||||
ACM = "ACM", "ACM"
|
|
||||||
OI = "OI", "OI"
|
|
||||||
|
|
||||||
|
|
||||||
class ProblemIOMode(models.TextChoices):
|
|
||||||
STANDARD = "Standard IO", "Standard IO"
|
|
||||||
FILE = "File IO", "File IO"
|
|
||||||
|
|
||||||
|
|
||||||
def _default_io_mode():
|
|
||||||
return {
|
|
||||||
"io_mode": ProblemIOMode.STANDARD,
|
|
||||||
"input": "input.txt",
|
|
||||||
"output": "output.txt",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Problem(models.Model):
|
class Problem(models.Model):
|
||||||
# display ID
|
# display ID
|
||||||
_id = models.TextField(db_index=True)
|
_id = models.TextField(db_index=True)
|
||||||
@@ -58,18 +40,14 @@ class Problem(models.Model):
|
|||||||
time_limit = models.IntegerField()
|
time_limit = models.IntegerField()
|
||||||
# MB
|
# MB
|
||||||
memory_limit = models.IntegerField()
|
memory_limit = models.IntegerField()
|
||||||
# io mode
|
|
||||||
io_mode = models.JSONField(default=_default_io_mode)
|
|
||||||
rule_type = models.TextField(choices=ProblemRuleType.choices)
|
|
||||||
visible = models.BooleanField(default=True, db_default=True)
|
visible = models.BooleanField(default=True, db_default=True)
|
||||||
difficulty = models.TextField(choices=Difficulty.choices)
|
difficulty = models.TextField(choices=Difficulty.choices)
|
||||||
tags = models.ManyToManyField(ProblemTag)
|
tags = models.ManyToManyField(ProblemTag)
|
||||||
source = models.TextField(null=True)
|
source = models.TextField(null=True)
|
||||||
|
# 预留:题目考察知识点,供未来 AI 分析使用(当前未接线)
|
||||||
prompt = models.TextField(null=True)
|
prompt = models.TextField(null=True)
|
||||||
# [{language: "python", code: "..."}]
|
# [{language: "python", code: "..."}]
|
||||||
answers = models.JSONField(null=True)
|
answers = models.JSONField(null=True)
|
||||||
# for OI mode
|
|
||||||
total_score = models.IntegerField(default=0, db_default=0)
|
|
||||||
submission_number = models.BigIntegerField(default=0, db_default=0)
|
submission_number = models.BigIntegerField(default=0, db_default=0)
|
||||||
accepted_number = models.BigIntegerField(default=0, db_default=0)
|
accepted_number = models.BigIntegerField(default=0, db_default=0)
|
||||||
# {JudgeStatus.ACCEPTED: 3, JudgeStatus.WRONG_ANSWER: 11}, the number means count
|
# {JudgeStatus.ACCEPTED: 3, JudgeStatus.WRONG_ANSWER: 11}, the number means count
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
from utils.api import UsernameSerializer, serializers
|
from utils.api import UsernameSerializer, serializers
|
||||||
@@ -9,7 +7,7 @@ from utils.serializers import (
|
|||||||
LanguageNameMultiChoiceField,
|
LanguageNameMultiChoiceField,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .models import Problem, ProblemIOMode, ProblemRuleType, ProblemTag
|
from .models import Problem, ProblemTag
|
||||||
from .utils import parse_problem_template
|
from .utils import parse_problem_template
|
||||||
|
|
||||||
|
|
||||||
@@ -48,20 +46,6 @@ class SQLTestCasePreviewSerializer(serializers.Serializer):
|
|||||||
mode = serializers.ChoiceField(choices=["query", "modify"])
|
mode = serializers.ChoiceField(choices=["query", "modify"])
|
||||||
|
|
||||||
|
|
||||||
class ProblemIOModeSerializer(serializers.Serializer):
|
|
||||||
io_mode = serializers.ChoiceField(choices=ProblemIOMode.choices)
|
|
||||||
input = serializers.CharField()
|
|
||||||
output = serializers.CharField()
|
|
||||||
|
|
||||||
def validate(self, attrs):
|
|
||||||
if attrs["input"] == attrs["output"]:
|
|
||||||
raise serializers.ValidationError("Invalid io mode")
|
|
||||||
for item in (attrs["input"], attrs["output"]):
|
|
||||||
if not re.match("^[a-zA-Z0-9.]+$", item):
|
|
||||||
raise serializers.ValidationError("Invalid io file name format")
|
|
||||||
return attrs
|
|
||||||
|
|
||||||
|
|
||||||
class CreateOrEditProblemSerializer(serializers.Serializer):
|
class CreateOrEditProblemSerializer(serializers.Serializer):
|
||||||
_id = serializers.CharField(max_length=32, allow_blank=True, allow_null=True)
|
_id = serializers.CharField(max_length=32, allow_blank=True, allow_null=True)
|
||||||
title = serializers.CharField(max_length=1024)
|
title = serializers.CharField(max_length=1024)
|
||||||
@@ -75,8 +59,6 @@ class CreateOrEditProblemSerializer(serializers.Serializer):
|
|||||||
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
||||||
languages = LanguageNameMultiChoiceField()
|
languages = LanguageNameMultiChoiceField()
|
||||||
template = serializers.DictField(child=serializers.CharField(min_length=1))
|
template = serializers.DictField(child=serializers.CharField(min_length=1))
|
||||||
rule_type = serializers.ChoiceField(choices=ProblemRuleType.choices)
|
|
||||||
io_mode = ProblemIOModeSerializer()
|
|
||||||
visible = serializers.BooleanField()
|
visible = serializers.BooleanField()
|
||||||
difficulty = serializers.ChoiceField(choices=Difficulty.choices)
|
difficulty = serializers.ChoiceField(choices=Difficulty.choices)
|
||||||
tags = serializers.ListField(child=serializers.CharField(max_length=32), allow_empty=False)
|
tags = serializers.ListField(child=serializers.CharField(max_length=32), allow_empty=False)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ from utils.api import APIError, APIView, CSRFExemptAPIView, validate_serializer
|
|||||||
from utils.openai import get_ai_client
|
from utils.openai import get_ai_client
|
||||||
from utils.shortcuts import natural_sort_key, rand_str
|
from utils.shortcuts import natural_sort_key, rand_str
|
||||||
|
|
||||||
from ..models import Problem, ProblemRuleType, ProblemTag
|
from ..models import Problem, ProblemTag
|
||||||
from ..serializers import (
|
from ..serializers import (
|
||||||
AddContestProblemSerializer,
|
AddContestProblemSerializer,
|
||||||
ContestProblemMakePublicSerializer,
|
ContestProblemMakePublicSerializer,
|
||||||
@@ -195,14 +195,6 @@ class TestCaseAPI(CSRFExemptAPIView, TestCaseZipProcessor):
|
|||||||
class ProblemBase(APIView):
|
class ProblemBase(APIView):
|
||||||
def common_checks(self, request):
|
def common_checks(self, request):
|
||||||
data = request.data
|
data = request.data
|
||||||
if data["rule_type"] == ProblemRuleType.OI:
|
|
||||||
total_score = 0
|
|
||||||
for item in data["test_case_score"]:
|
|
||||||
if item["score"] <= 0:
|
|
||||||
return "Invalid score"
|
|
||||||
else:
|
|
||||||
total_score += item["score"]
|
|
||||||
data["total_score"] = total_score
|
|
||||||
data["languages"] = list(data["languages"])
|
data["languages"] = list(data["languages"])
|
||||||
|
|
||||||
# SQL 题校验:.sql 测试点与 .in/.out 沙箱判题互斥,SQL 必须是唯一语言
|
# SQL 题校验:.sql 测试点与 .in/.out 沙箱判题互斥,SQL 必须是唯一语言
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class SubmissionModelSerializer(serializers.ModelSerializer):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
# 不显示submission info的serializer, 用于ACM rule_type
|
# 不显示submission info的serializer, 用于非管理员查看他人提交
|
||||||
class SubmissionSafeModelSerializer(serializers.ModelSerializer):
|
class SubmissionSafeModelSerializer(serializers.ModelSerializer):
|
||||||
problem = serializers.SlugRelatedField(read_only=True, slug_field="_id")
|
problem = serializers.SlugRelatedField(read_only=True, slug_field="_id")
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from judge.tasks import judge_task
|
|||||||
from options.options import SysOptions
|
from options.options import SysOptions
|
||||||
|
|
||||||
# from judge.dispatcher import JudgeDispatcher
|
# from judge.dispatcher import JudgeDispatcher
|
||||||
from problem.models import Problem, ProblemRuleType
|
from problem.models import Problem
|
||||||
from utils.api import APIView, AsyncAPIView, validate_serializer
|
from utils.api import APIView, AsyncAPIView, validate_serializer
|
||||||
from utils.cache import cache
|
from utils.cache import cache
|
||||||
from utils.captcha import Captcha
|
from utils.captcha import Captcha
|
||||||
@@ -116,10 +116,7 @@ class SubmissionAPI(AsyncAPIView):
|
|||||||
if not submission.check_user_permission(request.user):
|
if not submission.check_user_permission(request.user):
|
||||||
return self.error("No permission for this submission")
|
return self.error("No permission for this submission")
|
||||||
|
|
||||||
if (
|
if request.user.is_admin_role():
|
||||||
submission.problem.rule_type == ProblemRuleType.OI
|
|
||||||
or request.user.is_admin_role()
|
|
||||||
):
|
|
||||||
submission_data = await self.async_serialize_data(SubmissionModelSerializer, submission)
|
submission_data = await self.async_serialize_data(SubmissionModelSerializer, submission)
|
||||||
else:
|
else:
|
||||||
submission_data = await self.async_serialize_data(SubmissionSafeModelSerializer, submission)
|
submission_data = await self.async_serialize_data(SubmissionSafeModelSerializer, submission)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oj.settings")
|
|||||||
django.setup()
|
django.setup()
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from account.models import User, UserProfile, AdminType, ProblemPermission
|
from account.models import User, UserProfile, AdminType, ProblemPermission
|
||||||
from problem.models import Problem, ProblemTag, ProblemRuleType
|
from problem.models import Problem, ProblemTag
|
||||||
from utils.constants import Difficulty
|
from utils.constants import Difficulty
|
||||||
|
|
||||||
admin_type_map = {0: AdminType.REGULAR_USER, 1: AdminType.STUDENT_ADMIN, 2: AdminType.SUPER_ADMIN}
|
admin_type_map = {0: AdminType.REGULAR_USER, 1: AdminType.STUDENT_ADMIN, 2: AdminType.SUPER_ADMIN}
|
||||||
@@ -154,7 +154,6 @@ def import_problems():
|
|||||||
print("%s test_case files don't exist, omitted" % data["title"])
|
print("%s test_case files don't exist, omitted" % data["title"])
|
||||||
continue
|
continue
|
||||||
data["test_case_score"] = test_case_score
|
data["test_case_score"] = test_case_score
|
||||||
data["rule_type"] = ProblemRuleType.ACM
|
|
||||||
data["template"] = {}
|
data["template"] = {}
|
||||||
data.pop("total_submit_number")
|
data.pop("total_submit_number")
|
||||||
data.pop("total_accepted_number")
|
data.pop("total_accepted_number")
|
||||||
|
|||||||
Reference in New Issue
Block a user