feat: SQL 题测试点预览接口

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 19:25:47 -06:00
parent f77b98d4d7
commit 803d6ca58d
3 changed files with 22 additions and 0 deletions

View File

@@ -42,6 +42,12 @@ class SQLConfigSerializer(serializers.Serializer):
order_sensitive = serializers.BooleanField(default=False) order_sensitive = serializers.BooleanField(default=False)
class SQLTestCasePreviewSerializer(serializers.Serializer):
init_sql = serializers.CharField(trim_whitespace=False)
ref_sql = serializers.CharField(trim_whitespace=False)
mode = serializers.ChoiceField(choices=["query", "modify"])
class ProblemIOModeSerializer(serializers.Serializer): class ProblemIOModeSerializer(serializers.Serializer):
io_mode = serializers.ChoiceField(choices=ProblemIOMode.choices) io_mode = serializers.ChoiceField(choices=ProblemIOMode.choices)
input = serializers.CharField() input = serializers.CharField()

View File

@@ -7,6 +7,7 @@ from ..views.admin import (
ProblemAPI, ProblemAPI,
ProblemFlowchartAIGen, ProblemFlowchartAIGen,
ProblemVisibleAPI, ProblemVisibleAPI,
SQLTestCasePreviewAPI,
StuckProblemsAPI, StuckProblemsAPI,
TestCaseAPI, TestCaseAPI,
TopACTrendAPI, TopACTrendAPI,
@@ -14,6 +15,7 @@ from ..views.admin import (
urlpatterns = [ urlpatterns = [
path("test_case", TestCaseAPI.as_view()), path("test_case", TestCaseAPI.as_view()),
path("sql_test_case_preview", SQLTestCasePreviewAPI.as_view()),
path("problem", ProblemAPI.as_view()), path("problem", ProblemAPI.as_view()),
path("problem/visible", ProblemVisibleAPI.as_view()), path("problem/visible", ProblemVisibleAPI.as_view()),
path("problem/stuck", StuckProblemsAPI.as_view()), path("problem/stuck", StuckProblemsAPI.as_view()),

View File

@@ -13,6 +13,7 @@ from django.http import StreamingHttpResponse
from account.decorators import ensure_created_by, problem_permission_required, teacher_admin_required from account.decorators import ensure_created_by, problem_permission_required, teacher_admin_required
from contest.models import Contest, ContestStatus from contest.models import Contest, ContestStatus
from judge.sql_runner import SQLCaseError, build_display
from submission.models import Submission from submission.models import Submission
from utils.api import APIError, APIView, CSRFExemptAPIView, validate_serializer from utils.api import APIError, APIView, CSRFExemptAPIView, validate_serializer
from utils.openai import get_ai_client from utils.openai import get_ai_client
@@ -28,6 +29,7 @@ from ..serializers import (
EditProblemSerializer, EditProblemSerializer,
ProblemAdminListSerializer, ProblemAdminListSerializer,
ProblemAdminSerializer, ProblemAdminSerializer,
SQLTestCasePreviewSerializer,
TestCaseUploadForm, TestCaseUploadForm,
) )
from ..utils import generate_sql_display from ..utils import generate_sql_display
@@ -676,3 +678,15 @@ class TopACTrendAPI(APIView):
) )
return self.success(result) return self.success(result)
class SQLTestCasePreviewAPI(APIView):
@validate_serializer(SQLTestCasePreviewSerializer)
@problem_permission_required
def post(self, request):
data = request.data
try:
display = build_display(data["init_sql"], data["ref_sql"], data["mode"])
except SQLCaseError as e:
return self.error(e.message)
return self.success(display)