Files
OnlineJudge/problem/serializers.py
2025-10-12 00:03:27 +08:00

248 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
from django import forms
from utils.api import UsernameSerializer, serializers
from utils.constants import Difficulty
from utils.serializers import (
LanguageNameMultiChoiceField,
LanguageNameChoiceField,
)
from .models import Problem, ProblemRuleType, ProblemTag, ProblemIOMode
from .utils import parse_problem_template
class TestCaseUploadForm(forms.Form):
file = forms.FileField()
class CreateSampleSerializer(serializers.Serializer):
input = serializers.CharField(trim_whitespace=False)
output = serializers.CharField(trim_whitespace=False)
class CreateAnswerSerializer(serializers.Serializer):
language = serializers.CharField()
code = serializers.CharField()
class CreateTestCaseScoreSerializer(serializers.Serializer):
input_name = serializers.CharField(max_length=32)
output_name = serializers.CharField(max_length=32)
score = serializers.IntegerField(min_value=0)
class CreateProblemCodeTemplateSerializer(serializers.Serializer):
pass
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):
_id = serializers.CharField(max_length=32, allow_blank=True, allow_null=True)
title = serializers.CharField(max_length=1024)
description = serializers.CharField()
input_description = serializers.CharField()
output_description = serializers.CharField()
samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=False)
test_case_id = serializers.CharField(max_length=32)
test_case_score = serializers.ListField(
child=CreateTestCaseScoreSerializer(), allow_empty=True
)
time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60)
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
languages = LanguageNameMultiChoiceField()
template = serializers.DictField(child=serializers.CharField(min_length=1))
rule_type = serializers.ChoiceField(
choices=[ProblemRuleType.ACM, ProblemRuleType.OI]
)
io_mode = ProblemIOModeSerializer()
visible = serializers.BooleanField()
difficulty = serializers.ChoiceField(choices=Difficulty.choices())
tags = serializers.ListField(
child=serializers.CharField(max_length=32), allow_empty=False
)
hint = serializers.CharField(allow_blank=True, allow_null=True)
source = serializers.CharField(max_length=256, allow_blank=True, allow_null=True)
prompt = serializers.CharField(allow_blank=True, allow_null=True)
answers = serializers.ListField(
child=CreateAnswerSerializer(),
allow_empty=True,
allow_null=True,
)
share_submission = serializers.BooleanField()
# 流程图相关字段
allow_flowchart = serializers.BooleanField(required=False, default=False)
show_flowchart = serializers.BooleanField(required=False, default=False)
mermaid_code = serializers.CharField(
allow_blank=True, allow_null=True, required=False
)
flowchart_hint = serializers.CharField(
allow_blank=True, allow_null=True, required=False
)
class CreateProblemSerializer(CreateOrEditProblemSerializer):
pass
class EditProblemSerializer(CreateOrEditProblemSerializer):
id = serializers.IntegerField()
class CreateContestProblemSerializer(CreateOrEditProblemSerializer):
contest_id = serializers.IntegerField()
class EditContestProblemSerializer(CreateOrEditProblemSerializer):
id = serializers.IntegerField()
contest_id = serializers.IntegerField()
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = ProblemTag
fields = "__all__"
class BaseProblemSerializer(serializers.ModelSerializer):
tags = serializers.SlugRelatedField(many=True, slug_field="name", read_only=True)
created_by = UsernameSerializer()
def get_public_template(self, obj):
ret = {}
for lang, code in obj.template.items():
ret[lang] = parse_problem_template(code)["template"]
return ret
class ProblemAdminSerializer(BaseProblemSerializer):
class Meta:
model = Problem
fields = "__all__"
class ProblemAdminListSerializer(BaseProblemSerializer):
class Meta:
model = Problem
fields = ["_id", "id", "title", "created_by", "visible", "create_time"]
class ProblemSerializer(BaseProblemSerializer):
template = serializers.SerializerMethodField("get_public_template")
class Meta:
model = Problem
exclude = (
"test_case_score",
"test_case_id",
"visible",
"is_public",
"answers",
)
def to_representation(self, instance):
data = super().to_representation(instance)
# 如果 allow_flowchart=False则不返回 flowchart 相关字段
if not instance.allow_flowchart:
flowchart_fields = ['mermaid_code', 'flowchart_data', 'flowchart_hint', 'show_flowchart']
for field in flowchart_fields:
data.pop(field, None)
return data
class ProblemListSerializer(BaseProblemSerializer):
class Meta:
model = Problem
fields = [
"id",
"_id",
"title",
"submission_number",
"accepted_number",
"difficulty",
"created_by",
"tags",
"contest",
"rule_type",
]
def to_representation(self, instance):
data = super().to_representation(instance)
# 如果 allow_flowchart=False则不返回 flowchart 相关字段
if not instance.allow_flowchart:
flowchart_fields = ['mermaid_code', 'flowchart_data', 'flowchart_hint', 'show_flowchart']
for field in flowchart_fields:
data.pop(field, None)
return data
class ProblemSafeSerializer(BaseProblemSerializer):
template = serializers.SerializerMethodField("get_public_template")
class Meta:
model = Problem
exclude = (
"test_case_score",
"test_case_id",
"visible",
"is_public",
"difficulty",
"submission_number",
"accepted_number",
"statistic_info",
"answers",
)
def to_representation(self, instance):
data = super().to_representation(instance)
# 如果 allow_flowchart=False则不返回 flowchart 相关字段
if not instance.allow_flowchart:
flowchart_fields = ['mermaid_code', 'flowchart_data', 'flowchart_hint', 'show_flowchart']
for field in flowchart_fields:
data.pop(field, None)
return data
class ContestProblemMakePublicSerializer(serializers.Serializer):
id = serializers.IntegerField()
display_id = serializers.CharField(max_length=32)
class AddContestProblemSerializer(serializers.Serializer):
contest_id = serializers.IntegerField()
problem_id = serializers.IntegerField()
display_id = serializers.CharField()
class TestCaseScoreSerializer(serializers.Serializer):
score = serializers.IntegerField(min_value=1)
input_name = serializers.CharField(max_length=32)
output_name = serializers.CharField(max_length=32)
class TemplateSerializer(serializers.Serializer):
prepend = serializers.CharField()
template = serializers.CharField()
append = serializers.CharField()
class AnswerSerializer(serializers.Serializer):
code = serializers.CharField()
language = LanguageNameChoiceField()