From 8456b765869b35fa46c43a29035ffd7d2f18fe28 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Sun, 29 Mar 2026 10:07:22 -0600 Subject: [PATCH] remove rank --- submission/api.py | 65 ++----------------- .../migrations/0007_remove_nominated.py | 15 +++++ submission/models.py | 1 - submission/schemas.py | 13 ---- 4 files changed, 20 insertions(+), 74 deletions(-) create mode 100644 submission/migrations/0007_remove_nominated.py diff --git a/submission/api.py b/submission/api.py index 7f8e3bf..cac2238 100644 --- a/submission/api.py +++ b/submission/api.py @@ -17,7 +17,6 @@ from .schemas import ( SubmissionOut, RatingScoreIn, TaskStatsOut, - TopSubmission, UserTag, ) @@ -44,10 +43,6 @@ def create_submission(request, payload: SubmissionIn): ) conversation.is_active = False conversation.save(update_fields=["is_active"]) - # 如果用户之前已参与排名,自动转移提名到新提交 - had_nomination = Submission.objects.filter( - user=request.user, task=task, nominated=True - ).update(nominated=False) > 0 Submission.objects.create( user=request.user, @@ -56,7 +51,6 @@ def create_submission(request, payload: SubmissionIn): css=payload.css, js=payload.js, conversation=conversation, - nominated=had_nomination, ) @@ -67,8 +61,10 @@ def list_submissions(request, filters: SubmissionFilter = Query(...)): """ 获取提交列表,支持按任务和用户过滤 """ - submissions = Submission.objects.select_related("task", "user").defer( - "html", "css", "js" + submissions = ( + Submission.objects.select_related("task", "user") + .defer("html", "css", "js") + .exclude(conversation__isnull=False, html__isnull=True, css__isnull=True, js__isnull=True) ) if filters.task_id: @@ -86,8 +82,6 @@ def list_submissions(request, filters: SubmissionFilter = Query(...)): else: submissions = submissions.filter(flag=filters.flag) - if filters.nominated is not None: - submissions = submissions.filter(nominated=filters.nominated) if filters.score_lt_threshold is not None: submissions = submissions.filter(score__lt=filters.score_lt_threshold) else: @@ -142,6 +136,7 @@ def list_by_user_task(request, user_id: int, task_id: int): ) return ( Submission.objects.filter(user_id=user_id, task_id=task_id) + .exclude(conversation__isnull=False, html__isnull=True, css__isnull=True, js__isnull=True) .select_related("task", "user") .defer("html", "css", "js") .annotate(my_score=user_rating_subquery) @@ -261,14 +256,6 @@ def get_task_stats(request, task_id: int, classname: Optional[str] = None): for u in students.filter(id__in=unrated_ids).order_by("classname", "username") ] - # Nominated count: distinct users with nominated=True (task-wide, not class-filtered) - nominated_count = ( - Submission.objects.filter(task=task, nominated=True) - .values("user_id") - .distinct() - .count() - ) - # Submission count distribution sub_counts = dict( Submission.objects.filter(task=task, user_id__in=submitted_ids) @@ -287,24 +274,6 @@ def get_task_stats(request, task_id: int, classname: Optional[str] = None): else: dist["count_4_plus"] += 1 - # Top 5 submissions by rating count - top_subs_qs = ( - Submission.objects.filter(task=task, user_id__in=student_ids) - .select_related("user") - .annotate(rating_count=Count("ratings")) - .order_by("-rating_count")[:5] - ) - top_submissions = [ - TopSubmission( - submission_id=str(s.id), - username=s.user.username, - classname=s.user.classname, - score=s.score, - rating_count=s.rating_count, - ) - for s in top_subs_qs - ] - # Flag stats (all submissions for this task, not grouped by user) flag_counts = dict( Submission.objects.filter(task=task, flag__isnull=False) @@ -324,11 +293,9 @@ def get_task_stats(request, task_id: int, classname: Optional[str] = None): unsubmitted_count=unsubmitted_count, average_score=average_score, unrated_count=unrated_count, - nominated_count=nominated_count, unsubmitted_users=unsubmitted_users, unrated_users=unrated_users, submission_count_distribution=SubmissionCountBucket(**dist), - top_submissions=top_submissions, flag_stats=flag_stats, classes=all_classes, ) @@ -393,25 +360,3 @@ def update_flag(request, submission_id: UUID, payload: FlagIn): return {"flag": submission.flag} -@router.put("/{submission_id}/nominate") -@login_required -def nominate_submission(request, submission_id: UUID): - """ - 学生将某条提交标记为"参与排名"。 - 同一用户同一题目只能有一条参与排名,旧的自动取消。 - """ - submission = get_object_or_404(Submission, id=submission_id) - - if submission.user != request.user: - raise HttpError(403, "只能提名自己的提交") - - Submission.objects.filter( - user=request.user, - task=submission.task, - nominated=True, - ).exclude(pk=submission.pk).update(nominated=False) - - submission.nominated = True - submission.save(update_fields=["nominated"]) - - return {"nominated": True} diff --git a/submission/migrations/0007_remove_nominated.py b/submission/migrations/0007_remove_nominated.py new file mode 100644 index 0000000..ec81016 --- /dev/null +++ b/submission/migrations/0007_remove_nominated.py @@ -0,0 +1,15 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("submission", "0006_add_raw_score_nominated"), + ] + + operations = [ + migrations.RemoveField( + model_name="submission", + name="nominated", + ), + ] diff --git a/submission/models.py b/submission/models.py index 70739f9..bbd3c41 100644 --- a/submission/models.py +++ b/submission/models.py @@ -49,7 +49,6 @@ class Submission(TimeStampedModel): verbose_name="标记", ) raw_score = models.FloatField(default=0.0, verbose_name="原始加权分") - nominated = models.BooleanField(default=False, db_index=True, verbose_name="参与排名") class Meta: ordering = ("-created",) diff --git a/submission/schemas.py b/submission/schemas.py index 8fd276e..dd0bb43 100644 --- a/submission/schemas.py +++ b/submission/schemas.py @@ -26,7 +26,6 @@ class SubmissionOut(Schema): js: Optional[str] = None conversation_id: Optional[UUID] = None flag: Optional[str] = None - nominated: bool = False submit_count: int = 0 created: str modified: str @@ -88,7 +87,6 @@ class SubmissionOut(Schema): "js": submission.js, "conversation_id": submission.conversation_id, "flag": submission.flag, - "nominated": submission.nominated, "created": submission.created.isoformat(), "modified": submission.modified.isoformat(), } @@ -112,7 +110,6 @@ class SubmissionFilter(Schema): score_min: Optional[float] = None score_max_exclusive: Optional[float] = None score_lt_threshold: Optional[float] = None - nominated: Optional[bool] = None ordering: Optional[str] = None grouped: Optional[bool] = True @@ -126,14 +123,6 @@ class UserTag(Schema): classname: str -class TopSubmission(Schema): - submission_id: str # UUID as string - username: str - classname: str - score: float - rating_count: int - - class SubmissionCountBucket(Schema): count_1: int # users with exactly 1 submission count_2: int # users with exactly 2 submissions @@ -153,11 +142,9 @@ class TaskStatsOut(Schema): unsubmitted_count: int average_score: Optional[float] unrated_count: int - nominated_count: int unsubmitted_users: list[UserTag] unrated_users: list[UserTag] submission_count_distribution: SubmissionCountBucket - top_submissions: list[TopSubmission] flag_stats: FlagStats classes: list[str]