This commit is contained in:
2026-03-30 09:34:38 -06:00
parent a12a665fde
commit 24ff67ec0c
14 changed files with 149 additions and 42 deletions

View File

@@ -170,15 +170,15 @@ class ProblemSetProgress(models.Model):
)
self.total_problems_count = problemset_problems.count()
# 获取当前题单中所有题目的ID集合
current_problem_ids = {str(psp.problem.id) for psp in problemset_problems}
# 获取当前题单中所有题目的ID集合(直接用 problem_id FK 字段,无需额外查询)
current_problem_ids = {str(psp.problem_id) for psp in problemset_problems}
# 清理已删除题目的进度记录
progress_detail_to_remove = []
for problem_id in self.progress_detail.keys():
if problem_id not in current_problem_ids:
progress_detail_to_remove.append(problem_id)
for problem_id in progress_detail_to_remove:
del self.progress_detail[problem_id]
@@ -187,7 +187,7 @@ class ProblemSetProgress(models.Model):
total_score = 0
for psp in problemset_problems:
problem_id = str(psp.problem.id)
problem_id = str(psp.problem_id)
if problem_id in self.progress_detail:
problem_progress = self.progress_detail[problem_id]
completed_count += 1

View File

@@ -183,16 +183,18 @@ class ProblemSetProblemSerializer(serializers.ModelSerializer):
def get_is_completed(self, obj):
"""获取当前用户是否已完成该题目"""
request = self.context.get("request")
if request and request.user.is_authenticated:
if not (request and request.user.is_authenticated):
return False
# 优先使用 view 层预取的进度对象,避免 N+1
progress = self.context.get("user_progress")
if progress is None:
try:
progress = ProblemSetProgress.objects.get(
problemset=obj.problemset, user=request.user
)
problem_id = str(obj.problem.id)
return problem_id in progress.progress_detail
except ProblemSetProgress.DoesNotExist:
return False
return False
return str(obj.problem.id) in progress.progress_detail
class AddProblemToSetSerializer(serializers.Serializer):

View File

@@ -137,11 +137,23 @@ class ProblemSetProblemAPI(APIView):
except ProblemSet.DoesNotExist:
return self.error("题单不存在")
problems = ProblemSetProblem.objects.filter(problemset=problem_set).order_by(
"order"
problems = (
ProblemSetProblem.objects.filter(problemset=problem_set)
.select_related("problem__created_by")
.prefetch_related("problem__tags")
.order_by("order")
)
# 预取当前用户的题单进度,供 get_is_completed 使用,避免 N+1
user_progress = None
if request.user.is_authenticated:
try:
user_progress = ProblemSetProgress.objects.get(
problemset=problem_set, user=request.user
)
except ProblemSetProgress.DoesNotExist:
pass
serializer = ProblemSetProblemSerializer(
problems, many=True, context={"request": request}
problems, many=True, context={"request": request, "user_progress": user_progress}
)
return self.success(serializer.data)