From d2216195657862e81ec303e3334288743724e088 Mon Sep 17 00:00:00 2001 From: zemal Date: Mon, 1 May 2017 13:03:48 +0800 Subject: [PATCH 1/5] Add problem_list api. Fix AC/Total count bug. --- problem/models.py | 16 +++++++++++----- problem/urls/oj.py | 5 +++-- problem/views/oj.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/problem/models.py b/problem/models.py index 17d4e5d0..8b373b0a 100644 --- a/problem/models.py +++ b/problem/models.py @@ -18,6 +18,12 @@ class ProblemRuleType(object): OI = "OI" +class ProblemDifficulty(object): + High = "High" + Mid = "Mid" + Low = "Low" + + class AbstractProblem(models.Model): title = models.CharField(max_length=128) # HTML @@ -49,19 +55,19 @@ class AbstractProblem(models.Model): difficulty = models.CharField(max_length=32) tags = models.ManyToManyField(ProblemTag) source = models.CharField(max_length=200, blank=True, null=True) - total_submit_number = models.IntegerField(default=0) - total_accepted_number = models.IntegerField(default=0) + total_submit_number = models.BigIntegerField(default=0) + total_accepted_number = models.BigIntegerField(default=0) class Meta: db_table = "problem" abstract = True def add_submission_number(self): - self.accepted_problem_number = models.F("total_submit_number") + 1 + self.total_submit_number=models.F("total_submit_number") + 1 self.save() def add_ac_number(self): - self.accepted_problem_number = models.F("total_accepted_number") + 1 + self.total_accepted_number=models.F("total_accepted_number") + 1 self.save() @@ -77,4 +83,4 @@ class ContestProblem(AbstractProblem): class Meta: db_table = "contest_problem" - unique_together = (("_id", "contest"), ) + unique_together = (("_id", "contest"),) diff --git a/problem/urls/oj.py b/problem/urls/oj.py index a7613f12..5e7e6bea 100644 --- a/problem/urls/oj.py +++ b/problem/urls/oj.py @@ -1,7 +1,8 @@ from django.conf.urls import url -from ..views.oj import ProblemTagAPI +from ..views.oj import ProblemTagAPI, ProblemAPI urlpatterns = [ - url(r"^problem/tags/?$", ProblemTagAPI.as_view(), name="problem_tag_list_api") + url(r"^problem/tags/?$", ProblemTagAPI.as_view(), name="problem_tag_list_api"), + url(r"^problems/?$", ProblemAPI.as_view(), name="problem_list_api"), ] diff --git a/problem/views/oj.py b/problem/views/oj.py index 94496cee..c21c06a5 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -1,8 +1,46 @@ +from django.db.models import Q, Count from utils.api import APIView -from ..models import ProblemTag +from ..models import ProblemTag, Problem +from ..serializers import ProblemSerializer, TagSerializer class ProblemTagAPI(APIView): def get(self, request): - return self.success([item.name for item in ProblemTag.objects.all().order_by("id")]) + tags = ProblemTag.objects.annotate(problem_number=Count("problem"))\ + .filter(problem_number__gt=0).order_by("-problem_number") + return self.success(TagSerializer(tags, many=True).data) + + +class ProblemAPI(APIView): + def get(self, request): + # 问题详情页 + problem_id = request.GET.get("id") + if problem_id: + try: + problem = Problem.objects.get(id=problem_id) + return self.success(ProblemSerializer(problem).data) + except Problem.DoesNotExist: + return self.error("Problem does not exist") + + problems = Problem.objects.filter(visible=True) + # 按照标签筛选 + tag_text = request.GET.get("tag", None) + if tag_text: + try: + tag = ProblemTag.objects.get(name=tag_text) + except ProblemTag.DoesNotExist: + return self.error("The Tag does not exist.") + problems = tag.problem_set.all().filter(visible=True) + + # 搜索的情况 + keyword = request.GET.get("keyword", "").strip() + if keyword: + problems = problems.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) + + # 难度筛选 + difficulty_rank = request.GET.get('difficulty', None) + if difficulty_rank: + problems = problems.filter(difficulty=difficulty_rank) + + return self.success(self.paginate_data(request, problems, ProblemSerializer)) From a96a23da2d3fc890b47af267c1119f19a446e680 Mon Sep 17 00:00:00 2001 From: zemal Date: Mon, 1 May 2017 13:20:26 +0800 Subject: [PATCH 2/5] Fix tests. --- problem/tests.py | 8 +++++--- problem/urls/admin.py | 2 +- problem/views/oj.py | 4 +--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/problem/tests.py b/problem/tests.py index d80262ae..fc9fa44b 100644 --- a/problem/tests.py +++ b/problem/tests.py @@ -17,7 +17,9 @@ class ProblemTagListAPITest(APITestCase): ProblemTag.objects.create(name="name2") resp = self.client.get(self.reverse("problem_tag_list_api")) self.assertSuccess(resp) - self.assertEqual(resp.data["data"], ["name1", "name2"]) + resp_data = resp.data['data'] + self.assertEqual(resp_data[0]["name"], "name1") + self.assertEqual(resp_data[1]["name"], "name2") class TestCaseUploadAPITest(APITestCase): @@ -76,9 +78,9 @@ class TestCaseUploadAPITest(APITestCase): self.assertEqual(f.read(), name + "\n" + name + "\n" + "end") -class ProblemAPITest(APITestCase): +class ProblemAdminAPITest(APITestCase): def setUp(self): - self.url = self.reverse("problem_api") + self.url = self.reverse("problem_admin_api") self.create_super_admin() self.data = {"_id": "A-110", "title": "test", "description": "

test

", "input_description": "test", "output_description": "test", "time_limit": 1000, "memory_limit": 256, "difficulty": "Low", diff --git a/problem/urls/admin.py b/problem/urls/admin.py index b4813c5b..d123f35b 100644 --- a/problem/urls/admin.py +++ b/problem/urls/admin.py @@ -4,6 +4,6 @@ from ..views.admin import ContestProblemAPI, ProblemAPI, TestCaseUploadAPI urlpatterns = [ url(r"^test_case/upload/?$", TestCaseUploadAPI.as_view(), name="test_case_upload_api"), - url(r"^problem/?$", ProblemAPI.as_view(), name="problem_api"), + url(r"^problem/?$", ProblemAPI.as_view(), name="problem_admin_api"), url(r"^contest/problem/?$", ContestProblemAPI.as_view(), name="contest_problem_api") ] diff --git a/problem/views/oj.py b/problem/views/oj.py index c21c06a5..bed7ed85 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -7,9 +7,7 @@ from ..serializers import ProblemSerializer, TagSerializer class ProblemTagAPI(APIView): def get(self, request): - tags = ProblemTag.objects.annotate(problem_number=Count("problem"))\ - .filter(problem_number__gt=0).order_by("-problem_number") - return self.success(TagSerializer(tags, many=True).data) + return self.success(TagSerializer(ProblemTag.objects.all(), many=True).data) class ProblemAPI(APIView): From 7a43982b7483382e5b8c80e4c4341d8af497586e Mon Sep 17 00:00:00 2001 From: zemal Date: Mon, 1 May 2017 13:30:47 +0800 Subject: [PATCH 3/5] fix ci --- problem/models.py | 4 ++-- problem/tests.py | 3 ++- problem/views/oj.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/problem/models.py b/problem/models.py index 8b373b0a..61cc8f44 100644 --- a/problem/models.py +++ b/problem/models.py @@ -63,11 +63,11 @@ class AbstractProblem(models.Model): abstract = True def add_submission_number(self): - self.total_submit_number=models.F("total_submit_number") + 1 + self.total_submit_number = models.F("total_submit_number") + 1 self.save() def add_ac_number(self): - self.total_accepted_number=models.F("total_accepted_number") + 1 + self.total_accepted_number = models.F("total_accepted_number") + 1 self.save() diff --git a/problem/tests.py b/problem/tests.py index fc9fa44b..0aeefb0c 100644 --- a/problem/tests.py +++ b/problem/tests.py @@ -29,7 +29,8 @@ class TestCaseUploadAPITest(APITestCase): self.create_super_admin() def test_filter_file_name(self): - self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), ["1.in", "1.out"]) + self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), + ["1.in", "1.out"]) self.assertEqual(self.api.filter_name_list(["2.in", "2.out"], spj=False), []) self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in"], spj=True), ["1.in", "2.in"]) diff --git a/problem/views/oj.py b/problem/views/oj.py index bed7ed85..ffce4051 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -1,4 +1,4 @@ -from django.db.models import Q, Count +from django.db.models import Q from utils.api import APIView from ..models import ProblemTag, Problem From feddec8a3fed2b3bced9592b3a60e53711054ea1 Mon Sep 17 00:00:00 2001 From: zemal Date: Mon, 1 May 2017 13:39:18 +0800 Subject: [PATCH 4/5] fix ci again. --- problem/tests.py | 2 +- problem/views/oj.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/problem/tests.py b/problem/tests.py index 0aeefb0c..caa6ad68 100644 --- a/problem/tests.py +++ b/problem/tests.py @@ -17,7 +17,7 @@ class ProblemTagListAPITest(APITestCase): ProblemTag.objects.create(name="name2") resp = self.client.get(self.reverse("problem_tag_list_api")) self.assertSuccess(resp) - resp_data = resp.data['data'] + resp_data = resp.data["data"] self.assertEqual(resp_data[0]["name"], "name1") self.assertEqual(resp_data[1]["name"], "name2") diff --git a/problem/views/oj.py b/problem/views/oj.py index ffce4051..611c2c96 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -37,7 +37,7 @@ class ProblemAPI(APIView): problems = problems.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) # 难度筛选 - difficulty_rank = request.GET.get('difficulty', None) + difficulty_rank = request.GET.get("difficulty", None) if difficulty_rank: problems = problems.filter(difficulty=difficulty_rank) From 570c63100a033cabb38d6ea28748bd374e8e0a32 Mon Sep 17 00:00:00 2001 From: zemal Date: Mon, 1 May 2017 15:52:17 +0800 Subject: [PATCH 5/5] Alter IntergerField to BigIntergerField. --- problem/migrations/0004_auto_20170501_0637.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 problem/migrations/0004_auto_20170501_0637.py diff --git a/problem/migrations/0004_auto_20170501_0637.py b/problem/migrations/0004_auto_20170501_0637.py new file mode 100644 index 00000000..5d55ace8 --- /dev/null +++ b/problem/migrations/0004_auto_20170501_0637.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2017-05-01 06:37 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('problem', '0003_auto_20170217_0820'), + ] + + operations = [ + migrations.AlterField( + model_name='contestproblem', + name='total_accepted_number', + field=models.BigIntegerField(default=0), + ), + migrations.AlterField( + model_name='contestproblem', + name='total_submit_number', + field=models.BigIntegerField(default=0), + ), + migrations.AlterField( + model_name='problem', + name='total_accepted_number', + field=models.BigIntegerField(default=0), + ), + migrations.AlterField( + model_name='problem', + name='total_submit_number', + field=models.BigIntegerField(default=0), + ), + ]