Skip to content

Commit 7b73a1c

Browse files
authored
Merge pull request #22 from segment-oj/extract-problem-description-ztl
extract problem description
2 parents e29e46b + 41c445c commit 7b73a1c

File tree

5 files changed

+89
-18
lines changed

5 files changed

+89
-18
lines changed

problem/decorator.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from rest_framework.response import Response
2+
from rest_framework import status
3+
from django.shortcuts import get_object_or_404
4+
from problem.models import Problem
5+
6+
7+
def view_hidden_problem_permission_required():
8+
def decorator(func):
9+
def _wrapped_view(request, pid, *args, **kwargs):
10+
problem = get_object_or_404(Problem, pid=pid)
11+
12+
if not problem.enabled and not request.user.has_perm("problem.view_hidden"):
13+
return Response(
14+
{"detail": "Problem is hidden."}, status=status.HTTP_403_FORBIDDEN
15+
)
16+
17+
return func(request, pid=pid, *args, **kwargs)
18+
19+
return _wrapped_view
20+
21+
return decorator

problem/serializers.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,38 @@
66
from segmentoj import tools
77

88
class ProblemSerializer(serializers.ModelSerializer):
9+
910
class Meta:
1011
model = Problem
1112
fields = [
12-
"pid",
13-
"date_added",
14-
"title",
13+
"pid",
14+
"date_added",
15+
"title",
1516
"description",
16-
"allow_html",
17-
"tags",
18-
"enabled",
19-
"memory_limit",
17+
"allow_html",
18+
"tags",
19+
"enabled",
20+
"memory_limit",
2021
"time_limit",
2122
]
2223

2324
depth = 0
2425
read_only_fields = ["id", "date_added"]
26+
extra_kwargs = {
27+
"description": {"write_only": True},
28+
}
29+
30+
class ProblemDescriptionSerializer(serializers.ModelSerializer):
31+
32+
class Meta:
33+
model = Problem
34+
fields = [
35+
"pid",
36+
"description",
37+
]
38+
39+
depth = 0
40+
read_only_fields = ["id"]
2541

2642
class TagSerializer(serializers.ModelSerializer):
2743

problem/tests.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from rest_framework.test import APIRequestFactory, force_authenticate
55

66
from .models import Problem
7-
from .views import ProblemView, TagView, TagListView
7+
from .views import ProblemView, ProblemDescriptionView, TagView, TagListView
88
from account.models import User
99

1010
# Create your tests here.
@@ -21,7 +21,6 @@ def setUp(self):
2121
def testZ_get_problem(self):
2222
ac_data = {
2323
"title": "Simple Problem",
24-
"description": "This is description",
2524
"pid": 5,
2625
"allow_html": False,
2726
"enabled": True,
@@ -38,7 +37,6 @@ def testZ_get_problem(self):
3837
self.assertIsNotNone(data)
3938

4039
self.assertEqual(data.get("title"), ac_data["title"])
41-
self.assertEqual(data.get("description"), ac_data["description"])
4240
self.assertEqual(data.get("pid"), ac_data["pid"])
4341
self.assertEqual(data.get("allow_html"), ac_data["allow_html"])
4442
self.assertEqual(data.get("enabled"), ac_data["enabled"])
@@ -87,6 +85,28 @@ def testW_change_problem(self):
8785
self.assertEqual(target.enabled, ac_data["enabled"])
8886

8987

88+
class ProblemDescriptionViewTest(TestCase):
89+
fixtures = ["testdatabase.yaml"]
90+
91+
def setUp(self):
92+
self.base_url = "/api/problem/{pid}/description"
93+
self.factory = APIRequestFactory()
94+
self.view = ProblemDescriptionView.as_view()
95+
96+
def testZ_get_problem_description(self):
97+
ac_data = {
98+
"description": "This is description"
99+
}
100+
101+
request = self.factory.get(self.base_url.format(pid=5))
102+
response = self.view(request, pid=5)
103+
self.assertEqual(response.status_code, status.HTTP_200_OK)
104+
105+
data = response.data.get("res")
106+
self.assertIsNotNone(data)
107+
self.assertEqual(data.get("description"), ac_data["description"])
108+
109+
90110
class TagViewTest(TestCase):
91111
fixtures = ["testdatabase.yaml"]
92112

problem/views.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,26 @@
1010

1111
from segmentoj import tools
1212
from problem.models import Problem, Tag
13-
from .serializers import ProblemSerializer, ProblemListSerializer, TagSerializer
14-
from segmentoj.decorator import syllable_required, parameter_required
13+
from .serializers import (
14+
ProblemSerializer,
15+
ProblemDescriptionSerializer,
16+
ProblemListSerializer,
17+
TagSerializer,
18+
)
19+
from segmentoj.decorator import (
20+
parameter_required,
21+
)
1522
from status.models import Status
23+
from .decorator import view_hidden_problem_permission_required
1624

1725

1826
class ProblemView(APIView):
1927
@method_decorator(parameter_required("pid"))
28+
@method_decorator(view_hidden_problem_permission_required())
2029
def get(self, request, pid):
2130
# Get the content of a problem
2231
problem = get_object_or_404(Problem, pid=pid)
2332

24-
if not problem.enabled and not request.user.has_perm("problem.view_hidden"):
25-
return Response(
26-
{"detail": "Problem is hidden."}, status=status.HTTP_403_FORBIDDEN
27-
)
28-
2933
ps = ProblemSerializer(problem)
3034
return Response({"res": ps.data}, status=status.HTTP_200_OK)
3135

@@ -60,6 +64,16 @@ def delete(self, request, pid):
6064
return Response(status=status.HTTP_204_NO_CONTENT)
6165

6266

67+
class ProblemDescriptionView(APIView):
68+
@method_decorator(parameter_required("pid"))
69+
@method_decorator(view_hidden_problem_permission_required())
70+
def get(self, request, pid):
71+
problem = get_object_or_404(Problem, pid=pid)
72+
73+
pds = ProblemDescriptionSerializer(problem)
74+
return Response({"res": pds.data}, status=status.HTTP_200_OK)
75+
76+
6377
class TagView(APIView):
6478
@method_decorator(parameter_required("tid"))
6579
def get(self, request, tid):
@@ -126,7 +140,6 @@ def process_data(x):
126140
status=status.HTTP_200_OK,
127141
)
128142

129-
130143
class ProblemListCountView(APIView):
131144
def get(self, request):
132145

segmentoj/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
# Problem
5353
path("api/problem", problem.views.ProblemView.as_view()),
5454
path("api/problem/<int:pid>", problem.views.ProblemView.as_view()),
55+
path("api/problem/<int:pid>/description", problem.views.ProblemDescriptionView.as_view()),
5556
path("api/problem/tag", problem.views.TagView.as_view()),
5657
path("api/problem/tag/<int:tid>", problem.views.TagView.as_view()),
5758
path("api/problem/list", problem.views.ProblemListView.as_view()),

0 commit comments

Comments
 (0)