From c31145f76e68ff8a3e36c7ee52bf67551b14d10d Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 30 Mar 2026 09:39:35 -0600 Subject: [PATCH] fix cache --- account/views/oj.py | 9 ++++++++- comment/views/oj.py | 29 ++++++++++++++++++++--------- problem/views/oj.py | 11 +++++++++-- utils/constants.py | 3 +++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/account/views/oj.py b/account/views/oj.py index 1b7909e..d53a9f9 100644 --- a/account/views/oj.py +++ b/account/views/oj.py @@ -16,7 +16,8 @@ from otpauth import OtpAuth from problem.models import Problem from submission.models import Submission, JudgeStatus -from utils.constants import ContestRuleType +from django.core.cache import cache +from utils.constants import ContestRuleType, CacheKey from options.options import SysOptions from utils.api import APIView, validate_serializer, CSRFExemptAPIView from utils.captcha import Captcha @@ -464,6 +465,11 @@ class UserActivityRankAPI(APIView): start = request.GET.get("start") if not start: return self.error("start time is required") + cache_key = f"{CacheKey.user_activity_rank}:{start}" + cached = cache.get(cache_key) + if cached is not None: + return self.success(cached) + hidden_names = User.objects.filter( Q(admin_type=AdminType.SUPER_ADMIN) | Q(is_disabled=True) ).values_list("username", flat=True) @@ -477,6 +483,7 @@ class UserActivityRankAPI(APIView): .annotate(count=Count("problem_id", distinct=True)) .order_by("-count")[:10] ) + cache.set(cache_key, data, 600) return self.success(data) diff --git a/comment/views/oj.py b/comment/views/oj.py index 776e6b0..deb968c 100644 --- a/comment/views/oj.py +++ b/comment/views/oj.py @@ -1,8 +1,10 @@ -from django.db.models import Avg +from django.core.cache import cache +from django.db.models import Avg, Count from django.db.models.functions import Round from comment.models import Comment from problem.models import Problem from utils.api import APIView +from utils.constants import CacheKey from account.decorators import login_required from utils.api.api import validate_serializer from comment.serializers import CreateCommentSerializer, CommentSerializer @@ -46,6 +48,7 @@ class CommentAPI(APIView): comprehensive_rating=data["comprehensive_rating"], content=data["content"], ) + cache.delete(f"{CacheKey.comment_stats}:{problem.id}") return self.success() @login_required @@ -65,16 +68,24 @@ class CommentAPI(APIView): class CommentStatisticsAPI(APIView): def get(self, request): problem_id = request.GET.get("problem_id") - comments = Comment.objects.select_related("problem").filter( - problem_id=problem_id - ) - if comments.count() == 0: - return self.success() + cache_key = f"{CacheKey.comment_stats}:{problem_id}" + cached = cache.get(cache_key) + if cached is not None: + return self.success(cached) - count = comments.count() - rating = comments.aggregate( + agg = Comment.objects.filter(problem_id=problem_id).aggregate( + count=Count("id"), description=Round(Avg("description_rating"), 2), difficulty=Round(Avg("difficulty_rating"), 2), comprehensive=Round(Avg("comprehensive_rating"), 2), ) - return self.success({"count": count, "rating": rating}) + if not agg["count"]: + return self.success() + + data = {"count": agg["count"], "rating": { + "description": agg["description"], + "difficulty": agg["difficulty"], + "comprehensive": agg["comprehensive"], + }} + cache.set(cache_key, data, 3600) + return self.success(data) diff --git a/problem/views/oj.py b/problem/views/oj.py index 5e6e77e..14c9133 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -19,12 +19,19 @@ from contest.models import ContestRuleType class ProblemTagAPI(APIView): def get(self, request): + keyword = request.GET.get("keyword", "") + cache_key = f"{CacheKey.problem_tags}:{keyword}" + cached = cache.get(cache_key) + if cached is not None: + return self.success(cached) + qs = ProblemTag.objects - keyword = request.GET.get("keyword") if keyword: qs = ProblemTag.objects.filter(name__icontains=keyword) tags = qs.annotate(problem_count=Count("problem")).filter(problem_count__gt=0) - return self.success(TagSerializer(tags, many=True).data) + data = TagSerializer(tags, many=True).data + cache.set(cache_key, data, 3600) + return self.success(data) class PickOneAPI(APIView): diff --git a/utils/constants.py b/utils/constants.py index ea5643f..e71d991 100644 --- a/utils/constants.py +++ b/utils/constants.py @@ -26,6 +26,9 @@ class CacheKey: contest_rank_cache = "contest_rank_cache" website_config = "website_config" problem_authors = "problem_authors" + problem_tags = "problem_tags" + comment_stats = "comment_stats" + user_activity_rank = "user_activity_rank" class Difficulty(Choices):