This commit is contained in:
2025-12-22 19:06:58 +08:00
parent 8a773ebc74
commit b1189e1a0b

View File

@@ -262,12 +262,16 @@ class UserBadgeAPI(APIView):
# 获取指定用户的徽章 # 获取指定用户的徽章
try: try:
target_user = User.objects.get(username=username, is_disabled=False) target_user = User.objects.get(username=username, is_disabled=False)
badges = UserBadge.objects.filter(user=target_user).order_by("-earned_time") badges = UserBadge.objects.filter(user=target_user).order_by(
"-earned_time"
)
except User.DoesNotExist: except User.DoesNotExist:
return self.error("用户不存在") return self.error("用户不存在")
else: else:
# 获取当前用户的徽章 # 获取当前用户的徽章
badges = UserBadge.objects.filter(user=request.user).order_by("-earned_time") badges = UserBadge.objects.filter(user=request.user).order_by(
"-earned_time"
)
serializer = UserBadgeSerializer(badges, many=True) serializer = UserBadgeSerializer(badges, many=True)
return self.success(serializer.data) return self.success(serializer.data)
@@ -307,7 +311,9 @@ class ProblemSetUserProgressAPI(APIView):
return self.error("题单不存在") return self.error("题单不存在")
# 获取所有参与该题单的用户进度,使用 select_related 预加载用户信息 # 获取所有参与该题单的用户进度,使用 select_related 预加载用户信息
progresses = ProblemSetProgress.objects.filter(problemset=problem_set).select_related('user') progresses = ProblemSetProgress.objects.filter(
problemset=problem_set
).select_related("user")
# 班级过滤 # 班级过滤
class_name = request.GET.get("class_name", "").strip() class_name = request.GET.get("class_name", "").strip()
@@ -322,13 +328,13 @@ class ProblemSetUserProgressAPI(APIView):
# 计算统计数据(基于所有数据,而非分页数据) # 计算统计数据(基于所有数据,而非分页数据)
# 使用一次查询获取所有统计数据 # 使用一次查询获取所有统计数据
stats = progresses.aggregate( stats = progresses.aggregate(
total=Count('id'), total=Count("id"),
completed=Count('id', filter=Q(is_completed=True)), completed=Count("id", filter=Q(is_completed=True)),
avg_progress=Avg("progress_percentage") avg_progress=Avg("progress_percentage"),
) )
total_count = stats['total'] total_count = stats["total"]
completed_count = stats['completed'] completed_count = stats["completed"]
avg_progress = stats['avg_progress'] or 0 avg_progress = stats["avg_progress"] or 0
# 获取分页参数用于预先收集当前页需要的问题ID # 获取分页参数用于预先收集当前页需要的问题ID
try: try:
@@ -343,7 +349,7 @@ class ProblemSetUserProgressAPI(APIView):
offset = 0 offset = 0
# 只从当前页的数据中收集问题ID避免遍历所有记录 # 只从当前页的数据中收集问题ID避免遍历所有记录
paginated_progresses = list(progresses[offset:offset + limit]) paginated_progresses = list(progresses[offset : offset + limit])
all_problem_ids = set() all_problem_ids = set()
for progress in paginated_progresses: for progress in paginated_progresses:
if progress.progress_detail: if progress.progress_detail:
@@ -352,7 +358,9 @@ class ProblemSetUserProgressAPI(APIView):
# 批量加载当前页所需的问题 # 批量加载当前页所需的问题
problems_dict = {} problems_dict = {}
if all_problem_ids: if all_problem_ids:
problems = Problem.objects.filter(id__in=all_problem_ids).only('id', '_id', 'title') problems = Problem.objects.filter(id__in=all_problem_ids).only(
"id", "_id", "title"
)
problems_dict = {str(problem.id): problem for problem in problems} problems_dict = {str(problem.id): problem for problem in problems}
# 将预加载的问题字典存储到 request 中,供序列化器使用 # 将预加载的问题字典存储到 request 中,供序列化器使用
@@ -365,10 +373,17 @@ class ProblemSetUserProgressAPI(APIView):
data["statistics"] = { data["statistics"] = {
"total": total_count, "total": total_count,
"completed": completed_count, "completed": completed_count,
"avg_progress": round(avg_progress, 2) "avg_progress": round(avg_progress, 2),
} }
# 返回问题 ID 列表 # 返回问题 ID 列表
data["problems"] = [problem.id for problem in problems_dict.values()] data["problems"] = [
{
"id": problem.id,
"_id": problem._id,
"title": problem.title,
}
for problem in problems_dict.values()
]
return self.success(data) return self.success(data)