Files
OnlineJudge/comment/views/oj.py
2026-03-30 09:39:35 -06:00

92 lines
3.2 KiB
Python

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
from submission.models import Submission, JudgeStatus
class CommentAPI(APIView):
@validate_serializer(CreateCommentSerializer)
@login_required
def post(self, request):
data = request.data
try:
problem = Problem.objects.get(id=data["problem_id"], visible=True)
except Problem.DoesNotExist:
self.error("problem is not exists")
try:
submission = (
Submission.objects.select_related("problem")
.filter(
user_id=request.user.id,
problem_id=data["problem_id"],
result=JudgeStatus.ACCEPTED,
)
.first()
)
except Submission.DoesNotExist:
self.error("submission is not exists or not accepted")
language = submission.language
if language == "Python3":
language = "Python"
Comment.objects.create(
user=request.user,
problem=problem,
submission=submission,
language=language,
description_rating=data["description_rating"],
difficulty_rating=data["difficulty_rating"],
comprehensive_rating=data["comprehensive_rating"],
content=data["content"],
)
cache.delete(f"{CacheKey.comment_stats}:{problem.id}")
return self.success()
@login_required
def get(self, request):
problem_id = request.GET.get("problem_id")
comment = (
Comment.objects.select_related("problem")
.filter(user=request.user, problem_id=problem_id)
.first()
)
if comment:
return self.success(CommentSerializer(comment).data)
else:
return self.success()
class CommentStatisticsAPI(APIView):
def get(self, request):
problem_id = request.GET.get("problem_id")
cache_key = f"{CacheKey.comment_stats}:{problem_id}"
cached = cache.get(cache_key)
if cached is not None:
return self.success(cached)
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),
)
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)