出题人
This commit is contained in:
@@ -6,12 +6,14 @@ from ..views.oj import (
|
|||||||
ProblemAPI,
|
ProblemAPI,
|
||||||
ContestProblemAPI,
|
ContestProblemAPI,
|
||||||
PickOneAPI,
|
PickOneAPI,
|
||||||
|
ProblemAuthorAPI,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("problem/tags", ProblemTagAPI.as_view()),
|
path("problem/tags", ProblemTagAPI.as_view()),
|
||||||
path("problem", ProblemAPI.as_view()),
|
path("problem", ProblemAPI.as_view()),
|
||||||
path("problem/beat_count", ProblemSolvedPeopleCount.as_view()),
|
path("problem/beat_count", ProblemSolvedPeopleCount.as_view()),
|
||||||
|
path("problem/author", ProblemAuthorAPI.as_view()),
|
||||||
path("pickone", PickOneAPI.as_view()),
|
path("pickone", PickOneAPI.as_view()),
|
||||||
path("contest/problem", ContestProblemAPI.as_view()),
|
path("contest/problem", ContestProblemAPI.as_view()),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import random
|
import random
|
||||||
from django.db.models import Q, Count
|
from django.db.models import Q, Count
|
||||||
|
from django.core.cache import cache
|
||||||
from account.models import User
|
from account.models import User
|
||||||
from submission.models import Submission, JudgeStatus
|
from submission.models import Submission, JudgeStatus
|
||||||
from utils.api import APIView
|
from utils.api import APIView
|
||||||
from account.decorators import check_contest_permission
|
from account.decorators import check_contest_permission
|
||||||
|
from utils.constants import CacheKey
|
||||||
from ..models import ProblemTag, Problem, ProblemRuleType
|
from ..models import ProblemTag, Problem, ProblemRuleType
|
||||||
from ..serializers import (
|
from ..serializers import (
|
||||||
ProblemSerializer,
|
ProblemSerializer,
|
||||||
@@ -82,6 +84,11 @@ class ProblemAPI(APIView):
|
|||||||
.filter(contest_id__isnull=True, visible=True)
|
.filter(contest_id__isnull=True, visible=True)
|
||||||
.order_by("-create_time")
|
.order_by("-create_time")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
author = request.GET.get("author")
|
||||||
|
if author:
|
||||||
|
problems = problems.filter(created_by__username=author)
|
||||||
|
|
||||||
# 按照标签筛选
|
# 按照标签筛选
|
||||||
tag_text = request.GET.get("tag")
|
tag_text = request.GET.get("tag")
|
||||||
if tag_text:
|
if tag_text:
|
||||||
@@ -98,6 +105,7 @@ class ProblemAPI(APIView):
|
|||||||
difficulty = request.GET.get("difficulty")
|
difficulty = request.GET.get("difficulty")
|
||||||
if difficulty:
|
if difficulty:
|
||||||
problems = problems.filter(difficulty=difficulty)
|
problems = problems.filter(difficulty=difficulty)
|
||||||
|
|
||||||
# 根据profile 为做过的题目添加标记
|
# 根据profile 为做过的题目添加标记
|
||||||
data = self.paginate_data(request, problems, ProblemListSerializer)
|
data = self.paginate_data(request, problems, ProblemListSerializer)
|
||||||
self._add_problem_status(request, data)
|
self._add_problem_status(request, data)
|
||||||
@@ -166,17 +174,44 @@ class ProblemSolvedPeopleCount(APIView):
|
|||||||
if submission_count == 0:
|
if submission_count == 0:
|
||||||
return self.success(rate)
|
return self.success(rate)
|
||||||
today = datetime.today()
|
today = datetime.today()
|
||||||
twoYearAge = datetime(today.year - 2, today.month, today.day, 0, 0)
|
years_ago = datetime(today.year - 2, today.month, today.day, 0, 0)
|
||||||
total_count = User.objects.filter(
|
total_count = User.objects.filter(
|
||||||
is_disabled=False, last_login__gte=twoYearAge
|
is_disabled=False, last_login__gte=years_ago
|
||||||
).count()
|
).count()
|
||||||
accepted_count = Submission.objects.filter(
|
accepted_count = Submission.objects.filter(
|
||||||
problem_id=problem_id,
|
problem_id=problem_id,
|
||||||
result=JudgeStatus.ACCEPTED,
|
result=JudgeStatus.ACCEPTED,
|
||||||
create_time__gte=twoYearAge,
|
create_time__gte=years_ago,
|
||||||
).aggregate(user_count=Count("user_id", distinct=True))["user_count"]
|
).aggregate(user_count=Count("user_id", distinct=True))["user_count"]
|
||||||
if accepted_count < total_count:
|
if accepted_count < total_count:
|
||||||
rate = "%.2f" % ((total_count - accepted_count) / total_count * 100)
|
rate = "%.2f" % ((total_count - accepted_count) / total_count * 100)
|
||||||
else:
|
else:
|
||||||
rate = "0"
|
rate = "0"
|
||||||
return self.success(rate)
|
return self.success(rate)
|
||||||
|
|
||||||
|
|
||||||
|
class ProblemAuthorAPI(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
# 统计出题用户
|
||||||
|
cached_data = cache.get(CacheKey.problem_authors)
|
||||||
|
if cached_data:
|
||||||
|
return self.success(cached_data)
|
||||||
|
|
||||||
|
authors = (
|
||||||
|
Problem.objects.filter(
|
||||||
|
visible=True, contest_id__isnull=True, created_by__is_disabled=False
|
||||||
|
)
|
||||||
|
.values("created_by__username")
|
||||||
|
.annotate(problem_count=Count("id"))
|
||||||
|
.order_by("-problem_count")
|
||||||
|
)
|
||||||
|
result = [
|
||||||
|
{
|
||||||
|
"username": author["created_by__username"],
|
||||||
|
"problem_count": author["problem_count"],
|
||||||
|
}
|
||||||
|
for author in authors
|
||||||
|
]
|
||||||
|
|
||||||
|
cache.set(CacheKey.problem_authors, result, 3600)
|
||||||
|
return self.success(result)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class CacheKey:
|
|||||||
waiting_queue = "waiting_queue"
|
waiting_queue = "waiting_queue"
|
||||||
contest_rank_cache = "contest_rank_cache"
|
contest_rank_cache = "contest_rank_cache"
|
||||||
website_config = "website_config"
|
website_config = "website_config"
|
||||||
|
problem_authors = "problem_authors"
|
||||||
|
|
||||||
|
|
||||||
class Difficulty(Choices):
|
class Difficulty(Choices):
|
||||||
|
|||||||
@@ -57,11 +57,6 @@ def datetime2str(value, format="iso-8601"):
|
|||||||
return value
|
return value
|
||||||
return value.strftime(format)
|
return value.strftime(format)
|
||||||
|
|
||||||
|
|
||||||
def timestamp2utcstr(value):
|
|
||||||
return datetime.datetime.utcfromtimestamp(value).isoformat()
|
|
||||||
|
|
||||||
|
|
||||||
def natural_sort_key(s, _nsre=re.compile(r"(\d+)")):
|
def natural_sort_key(s, _nsre=re.compile(r"(\d+)")):
|
||||||
return [int(text) if text.isdigit() else text.lower()
|
return [int(text) if text.isdigit() else text.lower()
|
||||||
for text in re.split(_nsre, s)]
|
for text in re.split(_nsre, s)]
|
||||||
|
|||||||
Reference in New Issue
Block a user