url(r"^api/", include("problem.urls.oj")),
urlpatterns = [
url(r"^problem/tags/?$", ProblemTagAPI.as_view(), name="problem_tag_list_api"),
url(r"^problem/?$", ProblemAPI.as_view(), name="problem_api"),
url(r"^pickone/?$", PickOneAPI.as_view(), name="pick_one_api"),
url(r"^contest/problem/?$", ContestProblemAPI.as_view(), name="contest_problem_api"),
]
class ProblemTagAPI(APIView):
def get(self, request):
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)
class ProblemTag(models.Model):
name = models.TextField()
class Meta:
db_table = "problem_tag"
class ProblemAPI(APIView):
@staticmethod
def _add_problem_status(request, queryset_values):
if request.user.is_authenticated:
profile = request.user.userprofile
acm_problems_status = profile.acm_problems_status.get("problems", {})
oi_problems_status = profile.oi_problems_status.get("problems", {})
# paginate data
results = queryset_values.get("results")
if results is not None:
problems = results
else:
problems = [queryset_values, ]
for problem in problems:
if problem["rule_type"] == ProblemRuleType.ACM:
problem["my_status"] = acm_problems_status.get(str(problem["id"]), {}).get("status")
else:
problem["my_status"] = oi_problems_status.get(str(problem["id"]), {}).get("status")
problem id / limit / tag / keyword(검색) / difficulty(난이도)
problem id
def get(self, request):
problem_id = request.GET.get("problem_id")
if problem_id:
try:
problem = Problem.objects.select_related("created_by") \\
.get(_id=problem_id, contest_id__isnull=True, visible=True)
problem_data = ProblemSerializer(problem).data
self._add_problem_status(request, problem_data)
return self.success(problem_data)
except Problem.DoesNotExist:
return self.error("Problem does not exist")
limit
limit = request.GET.get("limit")
if not limit:
return self.error("Limit is needed")
tag
tag_text = request.GET.get("tag")
if tag_text:
problems = problems.filter(tags__name=tag_text)
keyword
keyword = request.GET.get("keyword", "").strip()
if keyword:
problems = problems.filter([Q](<https://sejong-creative-semester-2021-2.notion.site/Django-316230daeb684662ad2582c05cb7b402>)(title__icontains=keyword) | [Q](<https://sejong-creative-semester-2021-2.notion.site/Django-316230daeb684662ad2582c05cb7b402>)(_id__icontains=keyword))
difficulty
difficulty = request.GET.get("difficulty")
if difficulty:
problems = problems.filter(difficulty=difficulty)
# 根据profile 为做过的题目添加标记
data = self.paginate_data(request, problems, ProblemSerializer)
self._add_problem_status(request, data)
return self.success(data)
ProblemRuleType
Problem
class PickOneAPI(APIView):
def get(self, request):
problems = Problem.objects.filter(contest_id__isnull=True, visible=True)
count = problems.count()
if count == 0:
return self.error("No problem to pick")
return self.success(problems[random.randint(0, count - 1)]._id)
class ContestProblemAPI(APIView):
def _add_problem_status(self, request, queryset_values):
if request.user.is_authenticated:
profile = request.user.userprofile
if self.contest.rule_type == ContestRuleType.ACM:
problems_status = profile.acm_problems_status.get("contest_problems", {})
else:
problems_status = profile.oi_problems_status.get("contest_problems", {})
for problem in queryset_values:
problem["my_status"] = problems_status.get(str(problem["id"]), {}).get("status")
@check_contest_permission(check_type="problems")
def get(self, request):
problem_id = request.GET.get("problem_id")
if problem_id:
try:
problem = Problem.objects.select_related("created_by").get(_id=problem_id,
contest=self.contest,
visible=True)
except Problem.DoesNotExist:
return self.error("Problem does not exist.")
if self.contest.problem_details_permission(request.user):
problem_data = ProblemSerializer(problem).data
self._add_problem_status(request, [problem_data, ])
else:
problem_data = ProblemSafeSerializer(problem).data
return self.success(problem_data)
contest_problems = Problem.objects.select_related("created_by").filter(contest=self.contest, visible=True)
if self.contest.problem_details_permission(request.user):
data = ProblemSerializer(contest_problems, many=True).data
self._add_problem_status(request, data)
else:
data = ProblemSafeSerializer(contest_problems, many=True).data
return self.success(data)
Problem