drop leftovers from the live leaderboard: no fake model rows, no second sort
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,14 +77,8 @@ class Command(BaseCommand):
|
||||
from progress.models import LeaderboardEntry
|
||||
|
||||
days = opts['days']
|
||||
scores = self._collect(period, days, include_zero=opts['include_zero'])
|
||||
if not opts['include_zero']:
|
||||
scores = [(uid, xp) for uid, xp in scores if xp > 0]
|
||||
|
||||
# ترتیبِ قطعی: امتیازِ بیشتر جلوتر، و در تساوی user_id کوچکتر جلوتر —
|
||||
# وگرنه دو اجرای پشتسرهم روی دادهی یکسان رتبههای متفاوت میدهند.
|
||||
scores.sort(key=lambda p: (-p[1], p[0]))
|
||||
scores = scores[:opts['limit']]
|
||||
# مرتبسازی و کنار گذاشتنِ XPی صفر را خودِ compute_scores انجام میدهد.
|
||||
scores = self._collect(period, days, include_zero=opts['include_zero'])[:opts['limit']]
|
||||
|
||||
label = period if period == 'all_time' else f'{period} ({days} روزِ اخیر)'
|
||||
if opts['dry_run']:
|
||||
|
||||
@@ -7,7 +7,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.throttling import ScopedRateThrottle
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .models import Character, LeaderboardEntry, StreakRecord, UserHearts, UserStats
|
||||
from .models import Character, StreakRecord, UserHearts, UserStats
|
||||
from .services import effective_current_streak
|
||||
|
||||
|
||||
@@ -129,26 +129,22 @@ class LeaderboardView(APIView):
|
||||
scores = cache.get_or_set(
|
||||
f'leaderboard:{period}', lambda: compute_scores(period), LEADERBOARD_CACHE_TTL,
|
||||
)
|
||||
entries = [
|
||||
LeaderboardEntry(user_id=uid, period=period, xp_in_period=xp, rank=rank)
|
||||
for rank, (uid, xp) in enumerate(scores, 1)
|
||||
]
|
||||
|
||||
# نام کاربر از accounts.User خونده میشه (فقط برای نمایش، بدون FK واقعی).
|
||||
from accounts.models import User as AccountUser
|
||||
user_ids = [e.user_id for e in entries]
|
||||
names = {u.id: u.name for u in AccountUser.objects.filter(id__in=user_ids)}
|
||||
names = dict(
|
||||
AccountUser.objects.filter(id__in=[uid for uid, _ in scores]).values_list('id', 'name')
|
||||
)
|
||||
|
||||
data = {
|
||||
'period': period,
|
||||
'entries': [
|
||||
{
|
||||
'rank': e.rank,
|
||||
'userId': str(e.user_id),
|
||||
'name': names.get(e.user_id, ''),
|
||||
'xpInPeriod': e.xp_in_period,
|
||||
'rank': rank,
|
||||
'userId': str(uid),
|
||||
'name': names.get(uid, ''),
|
||||
'xpInPeriod': xp,
|
||||
}
|
||||
for e in entries
|
||||
for rank, (uid, xp) in enumerate(scores, 1)
|
||||
],
|
||||
}
|
||||
return Response(LeaderboardResponseSerializer(data).data)
|
||||
|
||||
Reference in New Issue
Block a user