refactor(reaction): 后台统计去掉排序,增加最近评价时间
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,9 @@
|
|||||||
from django.db.models import Count, F, FloatField, Q
|
from django.db.models import Count, F, Max, Q
|
||||||
from django.db.models.functions import Cast
|
|
||||||
|
|
||||||
from account.decorators import super_admin_required
|
from account.decorators import super_admin_required
|
||||||
from reaction.models import Reaction, ReactionType
|
from reaction.models import Reaction, ReactionType
|
||||||
from utils.api import APIView
|
from utils.api import APIView
|
||||||
|
|
||||||
MIN_USERS_FOR_RATIO = 3
|
|
||||||
DEFAULT_ORDERING = "-users"
|
|
||||||
|
|
||||||
|
|
||||||
class ReactionStatsAPI(APIView):
|
class ReactionStatsAPI(APIView):
|
||||||
@super_admin_required
|
@super_admin_required
|
||||||
@@ -15,27 +11,15 @@ class ReactionStatsAPI(APIView):
|
|||||||
queryset = (
|
queryset = (
|
||||||
Reaction.objects.values(pid=F("problem___id"), title=F("problem__title"))
|
Reaction.objects.values(pid=F("problem___id"), title=F("problem__title"))
|
||||||
.annotate(users=Count("user", distinct=True))
|
.annotate(users=Count("user", distinct=True))
|
||||||
|
.annotate(last_time=Max("create_time"))
|
||||||
.annotate(**{t.value: Count("id", filter=Q(type=t.value)) for t in ReactionType})
|
.annotate(**{t.value: Count("id", filter=Q(type=t.value)) for t in ReactionType})
|
||||||
.annotate(**{f"{t.value}_ratio": Cast(t.value, FloatField()) / Cast("users", FloatField()) for t in ReactionType})
|
.order_by("-users")
|
||||||
)
|
)
|
||||||
|
|
||||||
problem_id = request.GET.get("problem")
|
problem_id = request.GET.get("problem")
|
||||||
if problem_id:
|
if problem_id:
|
||||||
queryset = queryset.filter(problem___id__iexact=problem_id, problem__contest_id__isnull=True)
|
queryset = queryset.filter(problem___id__iexact=problem_id, problem__contest_id__isnull=True)
|
||||||
|
|
||||||
ordering = request.GET.get("ordering") or DEFAULT_ORDERING
|
|
||||||
prefix = "-" if ordering.startswith("-") else ""
|
|
||||||
field = ordering.lstrip("-")
|
|
||||||
if field == "users":
|
|
||||||
order_by = f"{prefix}users"
|
|
||||||
elif field in ReactionType.values:
|
|
||||||
# 按占比排序时过滤低样本,避免 1 人点 1 个就冲到 100%
|
|
||||||
queryset = queryset.filter(users__gte=MIN_USERS_FOR_RATIO)
|
|
||||||
order_by = f"{prefix}{field}_ratio"
|
|
||||||
else:
|
|
||||||
order_by = DEFAULT_ORDERING
|
|
||||||
|
|
||||||
queryset = queryset.order_by(order_by)
|
|
||||||
data = self.paginate_data(request, queryset)
|
data = self.paginate_data(request, queryset)
|
||||||
data["results"] = list(data["results"])
|
data["results"] = list(data["results"])
|
||||||
return self.success(data)
|
return self.success(data)
|
||||||
|
|||||||
Reference in New Issue
Block a user