fix(achievement): distinct() 前必须 order_by() 清掉默认排序
Submission.Meta 有 ordering=("-create_time",),Django 会把排序字段
并入 DISTINCT,导致 _languages 每条提交各成一行——生产环境实测
某用户 659 条而不是 5 种语言。
recompute 侥幸正确只因 .count() 会清排序,两个实现同一个量却不一致。
三处 distinct() 全部显式加 order_by()。
由 check_achievement_deploy 的自检项发现。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -103,7 +103,7 @@ class AcceptedCount(BaseMetric):
|
||||
metrics["accepted_count"] = metrics.get("accepted_count", 0) + 1
|
||||
|
||||
def recompute(self, user):
|
||||
return _practice_submissions(user.id).filter(result__in=ACCEPTED_RESULTS).values("problem_id").distinct().count()
|
||||
return _practice_submissions(user.id).filter(result__in=ACCEPTED_RESULTS).order_by().values("problem_id").distinct().count()
|
||||
|
||||
|
||||
@metric("submission_count", "提交总数", "提交次数(不含比赛)")
|
||||
@@ -181,10 +181,14 @@ class LanguagesUsed(BaseMetric):
|
||||
metrics["languages_used"] = len(seen)
|
||||
|
||||
def recompute(self, user):
|
||||
return _practice_submissions(user.id).values("language").distinct().count()
|
||||
return _practice_submissions(user.id).order_by().values("language").distinct().count()
|
||||
|
||||
def recompute_state(self, user):
|
||||
return {"_languages": list(_practice_submissions(user.id).values_list("language", flat=True).distinct())}
|
||||
# order_by() 不能省:Submission.Meta 有默认排序 ("-create_time",),
|
||||
# Django 会把排序字段并入 DISTINCT,于是每条提交各成一行——
|
||||
# 实测某用户返回 659 条而不是 5 种语言。
|
||||
# recompute 侥幸正确只是因为 .count() 会清掉排序,不能依赖这一点。
|
||||
return {"_languages": list(_practice_submissions(user.id).order_by().values_list("language", flat=True).distinct())}
|
||||
|
||||
|
||||
@metric("contest_joined", "参赛场次", "参加过的比赛数量(本指标是比赛维度,不受比赛提交不计入的限制)")
|
||||
@@ -194,7 +198,7 @@ class ContestJoined(BaseMetric):
|
||||
return
|
||||
|
||||
def recompute(self, user):
|
||||
return Submission.objects.filter(user_id=user.id, contest_id__isnull=False).values("contest_id").distinct().count()
|
||||
return Submission.objects.filter(user_id=user.id, contest_id__isnull=False).order_by().values("contest_id").distinct().count()
|
||||
|
||||
|
||||
@metric("badge_count", "题单奖章数", "获得的题单奖章数量")
|
||||
|
||||
Reference in New Issue
Block a user