feat: add problem yearly AC rate API endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ from ..views.oj import (
|
||||
ProblemAuthorAPI,
|
||||
ProblemSolvedPeopleCount,
|
||||
ProblemTagAPI,
|
||||
ProblemYearlyACRateAPI,
|
||||
SimilarProblemAPI,
|
||||
)
|
||||
|
||||
@@ -16,6 +17,7 @@ urlpatterns = [
|
||||
path("problem/beat_count", ProblemSolvedPeopleCount.as_view()),
|
||||
path("problem/similar", SimilarProblemAPI.as_view()),
|
||||
path("problem/author", ProblemAuthorAPI.as_view()),
|
||||
path("problem/yearly_ac", ProblemYearlyACRateAPI.as_view()),
|
||||
path("pickone", PickOneAPI.as_view()),
|
||||
path("contest/problem", ContestProblemAPI.as_view()),
|
||||
]
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db.models import Count, Q
|
||||
from django.db.models.functions import ExtractYear
|
||||
|
||||
from account.decorators import check_contest_permission
|
||||
from account.models import User
|
||||
@@ -279,4 +280,53 @@ class ProblemAuthorAPI(APIView):
|
||||
]
|
||||
|
||||
cache.set(cache_key, result, 7200)
|
||||
|
||||
|
||||
class ProblemYearlyACRateAPI(APIView):
|
||||
def get(self, request):
|
||||
problem_id = request.GET.get("problem_id")
|
||||
if not problem_id:
|
||||
return self.error("problem_id is required")
|
||||
|
||||
cache_key = f"{CacheKey.problem_yearly_ac}:{problem_id}"
|
||||
cached = cache.get(cache_key)
|
||||
if cached is not None:
|
||||
return self.success(cached)
|
||||
|
||||
try:
|
||||
problem = Problem.objects.get(
|
||||
_id=problem_id, contest_id__isnull=True, visible=True
|
||||
)
|
||||
except Problem.DoesNotExist:
|
||||
return self.error("Problem does not exist")
|
||||
|
||||
rows = (
|
||||
Submission.objects.filter(
|
||||
problem_id=problem.id,
|
||||
contest_id__isnull=True,
|
||||
)
|
||||
.exclude(result__in=[JudgeStatus.PENDING, JudgeStatus.JUDGING])
|
||||
.annotate(year=ExtractYear("create_time"))
|
||||
.values("year")
|
||||
.annotate(
|
||||
total=Count("id"),
|
||||
accepted=Count("id", filter=Q(result=JudgeStatus.ACCEPTED)),
|
||||
)
|
||||
.order_by("year")
|
||||
)
|
||||
|
||||
data = [
|
||||
{
|
||||
"year": row["year"],
|
||||
"total": row["total"],
|
||||
"accepted": row["accepted"],
|
||||
"ac_rate": round(row["accepted"] / row["total"] * 100, 2)
|
||||
if row["total"] > 0
|
||||
else 0.0,
|
||||
}
|
||||
for row in rows
|
||||
]
|
||||
|
||||
cache.set(cache_key, data, 3600)
|
||||
return self.success(data)
|
||||
return self.success(result)
|
||||
|
||||
Reference in New Issue
Block a user