chore: 删 11 个无引用序列化器;撤回一处误判的"修复"
## 撤回:增删题单题目本来就会重算进度,我诊断错了
上一个 commit 我给 ProblemSetProblemAdminAPI 的 post/delete 加了显式的
sync_all_progress_for_problemset,理由是"增删题目不重算进度"。**那是错的。**
problemset/signals.py 里有 post_save / post_delete 信号接收器,
在 ProblemSetProblem 变化时同步进度**并重算奖章**,且 apps.py 的 ready()
确实导入了 signals。我的显式调用只是让同一件事做两遍。
更该记住的是**为什么当时没发现**:那一版测试只看"进度有没有更新",
而信号和我的调用都会让它更新 —— 分不出是谁干的,所以照样是绿的。
这次的测试改成先撤掉调用再验,并直接断言信号已注册在 post_save/post_delete 上,
这样才真的有区分力。6/6 通过。
同一批修复里的另外 5 条经复核都成立,保留。特别是「移除用户留下孤儿奖章」——
signals.py 里**没有**针对 ProblemSetProgress 的 post_delete,那条必须自己清。
## 删无引用序列化器(-78 行)
全仓 106 个序列化器,11 个无任何引用:
account: FileUploadForm, GenerateUserSerializer, SSOSerializer,
UserChangeEmailSerializer, UserChangePasswordSerializer,
UsernameOrEmailCheckSerializer
contest: CreateContestAnnouncementSerializer, EditContestAnnouncementSerializer
problem: CreateProblemCodeTemplateSerializer
flowchart: FlowchartSubmissionMergedSerializer, FlowchartSubmissionSummarySerializer
前 8 个是上一个 commit 删掉的视图留下的(FileUploadForm 正是
SimditorFileUploadAPIView 用的),后 3 个是原本就死的。
检测器同样做了自检:拿 3 个明确在用的序列化器反测,没有误判。
另外确认这 11 个都没有字符串形式的动态引用。
`ruff check .` 全绿。行尾未被改动(上一轮踩过这个坑,这次脚本里加了断言)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,35 +10,12 @@ class UserLoginSerializer(serializers.Serializer):
|
|||||||
password = serializers.CharField()
|
password = serializers.CharField()
|
||||||
|
|
||||||
|
|
||||||
class UsernameOrEmailCheckSerializer(serializers.Serializer):
|
|
||||||
username = serializers.CharField(required=False)
|
|
||||||
email = serializers.EmailField(required=False)
|
|
||||||
|
|
||||||
|
|
||||||
class UserRegisterSerializer(serializers.Serializer):
|
class UserRegisterSerializer(serializers.Serializer):
|
||||||
username = serializers.CharField(max_length=32)
|
username = serializers.CharField(max_length=32)
|
||||||
password = serializers.CharField(min_length=6)
|
password = serializers.CharField(min_length=6)
|
||||||
email = serializers.EmailField(max_length=64)
|
email = serializers.EmailField(max_length=64)
|
||||||
|
|
||||||
|
|
||||||
class UserChangePasswordSerializer(serializers.Serializer):
|
|
||||||
old_password = serializers.CharField()
|
|
||||||
new_password = serializers.CharField(min_length=6)
|
|
||||||
|
|
||||||
|
|
||||||
class UserChangeEmailSerializer(serializers.Serializer):
|
|
||||||
password = serializers.CharField()
|
|
||||||
new_email = serializers.EmailField(max_length=64)
|
|
||||||
|
|
||||||
|
|
||||||
class GenerateUserSerializer(serializers.Serializer):
|
|
||||||
prefix = serializers.CharField(max_length=16, allow_blank=True)
|
|
||||||
suffix = serializers.CharField(max_length=16, allow_blank=True)
|
|
||||||
number_from = serializers.IntegerField()
|
|
||||||
number_to = serializers.IntegerField()
|
|
||||||
password_length = serializers.IntegerField(max_value=16, default=8)
|
|
||||||
|
|
||||||
|
|
||||||
class ImportUserSerializer(serializers.Serializer):
|
class ImportUserSerializer(serializers.Serializer):
|
||||||
users = serializers.ListField(child=serializers.ListField(child=serializers.CharField(max_length=64)))
|
users = serializers.ListField(child=serializers.ListField(child=serializers.CharField(max_length=64)))
|
||||||
|
|
||||||
@@ -130,18 +107,10 @@ class EditUserProfileSerializer(serializers.Serializer):
|
|||||||
language = serializers.CharField(max_length=32, allow_blank=True, required=False)
|
language = serializers.CharField(max_length=32, allow_blank=True, required=False)
|
||||||
|
|
||||||
|
|
||||||
class SSOSerializer(serializers.Serializer):
|
|
||||||
token = serializers.CharField()
|
|
||||||
|
|
||||||
|
|
||||||
class ImageUploadForm(forms.Form):
|
class ImageUploadForm(forms.Form):
|
||||||
image = forms.FileField()
|
image = forms.FileField()
|
||||||
|
|
||||||
|
|
||||||
class FileUploadForm(forms.Form):
|
|
||||||
file = forms.FileField()
|
|
||||||
|
|
||||||
|
|
||||||
class RankInfoSerializer(serializers.ModelSerializer):
|
class RankInfoSerializer(serializers.ModelSerializer):
|
||||||
user = UsernameSerializer()
|
user = UsernameSerializer()
|
||||||
|
|
||||||
|
|||||||
@@ -50,20 +50,6 @@ class ContestAnnouncementSerializer(serializers.ModelSerializer):
|
|||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
class CreateContestAnnouncementSerializer(serializers.Serializer):
|
|
||||||
contest_id = serializers.IntegerField()
|
|
||||||
title = serializers.CharField(max_length=128)
|
|
||||||
content = serializers.CharField()
|
|
||||||
visible = serializers.BooleanField()
|
|
||||||
|
|
||||||
|
|
||||||
class EditContestAnnouncementSerializer(serializers.Serializer):
|
|
||||||
id = serializers.IntegerField()
|
|
||||||
title = serializers.CharField(max_length=128, required=False)
|
|
||||||
content = serializers.CharField(required=False, allow_blank=True)
|
|
||||||
visible = serializers.BooleanField(required=False)
|
|
||||||
|
|
||||||
|
|
||||||
class ContestPasswordVerifySerializer(serializers.Serializer):
|
class ContestPasswordVerifySerializer(serializers.Serializer):
|
||||||
contest_id = serializers.IntegerField()
|
contest_id = serializers.IntegerField()
|
||||||
password = serializers.CharField(max_length=30, required=True)
|
password = serializers.CharField(max_length=30, required=True)
|
||||||
|
|||||||
@@ -74,32 +74,3 @@ class FlowchartSubmissionListSerializer(serializers.ModelSerializer):
|
|||||||
"evaluation_time",
|
"evaluation_time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class FlowchartSubmissionSummarySerializer(serializers.ModelSerializer):
|
|
||||||
"""用于AI详情页面的极简序列化器,只包含必要字段"""
|
|
||||||
|
|
||||||
problem_title = serializers.CharField(source="problem.title")
|
|
||||||
problem__id = serializers.CharField(source="problem._id")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = FlowchartSubmission
|
|
||||||
fields = [
|
|
||||||
"id",
|
|
||||||
"problem__id",
|
|
||||||
"problem_title",
|
|
||||||
"ai_score",
|
|
||||||
"ai_grade",
|
|
||||||
"create_time",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class FlowchartSubmissionMergedSerializer(serializers.Serializer):
|
|
||||||
"""合并后的流程图提交序列化器"""
|
|
||||||
|
|
||||||
problem__id = serializers.CharField()
|
|
||||||
problem_title = serializers.CharField()
|
|
||||||
submission_count = serializers.IntegerField()
|
|
||||||
best_score = serializers.FloatField()
|
|
||||||
best_grade = serializers.CharField()
|
|
||||||
latest_submission_time = serializers.DateTimeField()
|
|
||||||
avg_score = serializers.FloatField()
|
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ class CreateTestCaseScoreSerializer(serializers.Serializer):
|
|||||||
score = serializers.IntegerField(min_value=0)
|
score = serializers.IntegerField(min_value=0)
|
||||||
|
|
||||||
|
|
||||||
class CreateProblemCodeTemplateSerializer(serializers.Serializer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SQLConfigSerializer(serializers.Serializer):
|
class SQLConfigSerializer(serializers.Serializer):
|
||||||
mode = serializers.ChoiceField(choices=["query", "modify"])
|
mode = serializers.ChoiceField(choices=["query", "modify"])
|
||||||
order_sensitive = serializers.BooleanField(default=False)
|
order_sensitive = serializers.BooleanField(default=False)
|
||||||
|
|||||||
@@ -166,10 +166,7 @@ class ProblemSetProblemAdminAPI(APIView):
|
|||||||
score=data.get("score", 0),
|
score=data.get("score", 0),
|
||||||
hint=data.get("hint", ""),
|
hint=data.get("hint", ""),
|
||||||
)
|
)
|
||||||
# 题目数就是进度的分母,加完必须重算:不重算的话已加入的学生进度百分比
|
# 进度和奖章由 problemset/signals.py 的 post_save 信号自动重算,这里不用管。
|
||||||
# 全是虚高的,而且原本标成"已完成"的人会一直是已完成。
|
|
||||||
# 手动同步接口(ProblemSetSyncAPI)前端没有调用点,所以只能在这里做。
|
|
||||||
ProblemSetProgress.sync_all_progress_for_problemset(problem_set)
|
|
||||||
|
|
||||||
return self.success("题目已添加到题单")
|
return self.success("题目已添加到题单")
|
||||||
|
|
||||||
@@ -215,8 +212,7 @@ class ProblemSetProblemAdminAPI(APIView):
|
|||||||
try:
|
try:
|
||||||
problem_set_problem = ProblemSetProblem.objects.get(id=problem_set_problem_id, problemset=problem_set)
|
problem_set_problem = ProblemSetProblem.objects.get(id=problem_set_problem_id, problemset=problem_set)
|
||||||
problem_set_problem.delete()
|
problem_set_problem.delete()
|
||||||
# 同上:分母变了,进度要重算
|
# 进度和奖章由 post_delete 信号自动重算
|
||||||
ProblemSetProgress.sync_all_progress_for_problemset(problem_set)
|
|
||||||
return self.success("题目已从题单中移除")
|
return self.success("题目已从题单中移除")
|
||||||
except ProblemSetProblem.DoesNotExist:
|
except ProblemSetProblem.DoesNotExist:
|
||||||
return self.error("题目不在该题单中")
|
return self.error("题目不在该题单中")
|
||||||
|
|||||||
Reference in New Issue
Block a user